summary refs log tree commit diff stats
path: root/tests/method
diff options
context:
space:
mode:
Diffstat (limited to 'tests/method')
-rw-r--r--tests/method/mmultim3.nim12
-rw-r--r--tests/method/t20515.nim20
-rw-r--r--tests/method/t22673.nim21
-rw-r--r--tests/method/tcompilegenerics.nim24
-rw-r--r--tests/method/tgeneric_methods.nim42
-rw-r--r--tests/method/tmapper.nim30
-rw-r--r--tests/method/tmethod.nim8
-rw-r--r--tests/method/tmethod_issues.nim170
-rw-r--r--tests/method/tmethod_various.nim79
-rw-r--r--tests/method/tmethods_old.nim12
-rw-r--r--tests/method/tmultim.nim97
-rw-r--r--tests/method/tmultimjs.nim73
-rw-r--r--tests/method/tnildispatcher.nim21
-rw-r--r--tests/method/treturn_var_t.nim25
-rw-r--r--tests/method/tsingle_methods.nim48
-rw-r--r--tests/method/tvtable.nim24
16 files changed, 706 insertions, 0 deletions
diff --git a/tests/method/mmultim3.nim b/tests/method/mmultim3.nim
new file mode 100644
index 000000000..a97248203
--- /dev/null
+++ b/tests/method/mmultim3.nim
@@ -0,0 +1,12 @@
+type
+    TObj* {.inheritable.} = object
+
+var myObj* : ref TObj
+
+method test123(a : ref TObj) {.base.} =
+    echo("Hi base!")
+
+proc testMyObj*() =
+    test123(myObj)
+
+
diff --git a/tests/method/t20515.nim b/tests/method/t20515.nim
new file mode 100644
index 000000000..1921f2e46
--- /dev/null
+++ b/tests/method/t20515.nim
@@ -0,0 +1,20 @@
+discard """
+  errormsg: "Base method 'zzz' requires explicit '{.gcsafe.}' to be GC-safe"
+  line: 10
+"""
+
+type
+  A = ref object of RootObj
+  B = ref object of A
+
+method zzz(a: A) {.base.} =
+  discard
+
+var s: seq[int]
+method zzz(a: B) =
+  echo s
+
+proc xxx(someObj: A) {.gcsafe.} =
+  someObj.zzz()
+
+xxx(B())
diff --git a/tests/method/t22673.nim b/tests/method/t22673.nim
new file mode 100644
index 000000000..1689e9d42
--- /dev/null
+++ b/tests/method/t22673.nim
@@ -0,0 +1,21 @@
+discard """
+  matrix: "--warningAsError:UseBase"
+"""
+
+# bug #22673
+type RefEntry = ref object of RootObj
+
+type RefFile = ref object of RefEntry
+    filename*: string
+    data*: string
+
+type RefDir = ref object of RefEntry
+    dirname*: string
+    files*: seq[RefFile]
+
+method name*(e: RefEntry): lent string {.base.} =
+  raiseAssert "Don't call the base method"
+
+method name*(e: RefFile): lent string = e.filename
+
+method name*(e: RefDir): lent string = e.dirname
\ No newline at end of file
diff --git a/tests/method/tcompilegenerics.nim b/tests/method/tcompilegenerics.nim
new file mode 100644
index 000000000..d0732895b
--- /dev/null
+++ b/tests/method/tcompilegenerics.nim
@@ -0,0 +1,24 @@
+discard """
+  matrix: "--mm:arc; --mm:refc"
+  output: '''
+newDNode base
+'''
+"""
+
+type
+  SNodeAny = ref object of RootObj
+  SNode[T] = ref object of SNodeAny
+    m: T
+  DNode[T] = ref object
+
+method getStr(s: SNode[float]): string {.base.} = "blahblah"
+
+method newDNode(s: SNodeAny) {.base.} =
+  echo "newDNode base"
+
+method newDNode[T](s: SNode[T]) =
+  echo "newDNode generic"
+
+let m = SNode[float]()
+let s = SNodeAny(m)
+newDnode(s)
\ No newline at end of file
diff --git a/tests/method/tgeneric_methods.nim b/tests/method/tgeneric_methods.nim
new file mode 100644
index 000000000..f8d068cc5
--- /dev/null
+++ b/tests/method/tgeneric_methods.nim
@@ -0,0 +1,42 @@
+discard """

+  matrix: "--mm:arc --multimethods:on -d:nimInternalNonVtablesTesting; --mm:refc --multimethods:on -d:nimInternalNonVtablesTesting"

+  output: '''wow2

+X 1

+X 3'''

+"""

+type

+  First[T] = ref object of RootObj

+    value: T

+

+  Second[T] = ref object of First[T]

+    value2: T

+

+method wow[T](y: int; x: First[T]) {.base.} =

+  echo "wow1"

+

+method wow[T](y: int; x: Second[T]) =

+  echo "wow2"

+

+var

+  x: Second[int]

+new(x)

+

+proc takeFirst(x: First[int]) =

+  wow(2, x)

+

+takeFirst(x)

+

+

+# bug #5479

+type

+  Base[T: static[int]] = ref object of RootObj

+

+method test[T](t: Base[T]) {.base.} =

+  echo "X ", t.T

+

+let ab = Base[1]()

+

+ab.test()

+

+let ac = Base[3]()

+ac.test()

diff --git a/tests/method/tmapper.nim b/tests/method/tmapper.nim
new file mode 100644
index 000000000..9162d0eec
--- /dev/null
+++ b/tests/method/tmapper.nim
@@ -0,0 +1,30 @@
+discard """
+  errormsg: "invalid declaration order; cannot attach 'step' to method defined here: tmapper.nim(22, 8)"
+  line: 25
+"""
+
+# bug #2590
+
+type
+  Console* = ref object
+    mapper*: Mapper
+
+  Mapper* = ref object of RootObj
+
+  Mapper2* = ref object of Mapper
+
+proc newMapper2*: Mapper2 =
+  new result
+
+proc newMapper*: Mapper =
+  result = newMapper2()
+
+method step*(m: Mapper2) {.base.} =
+  echo "Mapper2"
+
+method step*(m: Mapper) {.base.} =
+  echo "Mapper"
+
+var console = Console()
+console.mapper = newMapper()
+console.mapper.step()
diff --git a/tests/method/tmethod.nim b/tests/method/tmethod.nim
new file mode 100644
index 000000000..005294d64
--- /dev/null
+++ b/tests/method/tmethod.nim
@@ -0,0 +1,8 @@
+discard """
+  errormsg: "\'method\' needs a parameter that has an object type"
+  file: "tmethod.nim"
+  line: 7
+"""
+
+method m(i: int): int =
+  return 5
diff --git a/tests/method/tmethod_issues.nim b/tests/method/tmethod_issues.nim
new file mode 100644
index 000000000..daaa46522
--- /dev/null
+++ b/tests/method/tmethod_issues.nim
@@ -0,0 +1,170 @@
+discard """
+  matrix: "--mm:arc; --mm:refc"
+  output: '''
+wof!
+wof!
+type A
+type B
+'''
+"""
+
+
+# bug #1659
+type Animal {.inheritable.} = ref object
+type Dog = ref object of Animal
+
+method say(a: Animal): auto {.base.} = "wat!"
+method say(a: Dog): auto = "wof!"
+
+proc saySomething(a: Animal): auto = a.say()
+
+method ec(a: Animal): auto {.base.} = echo "wat!"
+method ec(a: Dog): auto = echo "wof!"
+
+proc ech(a: Animal): auto = a.ec()
+
+var a = Dog()
+echo saySomething(a)
+ech a
+
+
+
+# bug #2401
+type MyClass = ref object of RootObj
+
+method HelloWorld*(obj: MyClass) {.base.} =
+  when defined(myPragma):
+    echo("Hello World")
+  # discard # with this line enabled it works
+
+var obj = MyClass()
+obj.HelloWorld()
+
+
+
+
+# bug #5432
+type
+  Iterator[T] = ref object of RootObj
+
+# base methods with `T` in the return type are okay
+method methodThatWorks*[T](i: Iterator[T]): T {.base.} =
+  discard
+
+# base methods without `T` (void or basic types) fail
+method methodThatFails*[T](i: Iterator[T]) {.base.} =
+  discard
+
+type
+  SpecificIterator1 = ref object of Iterator[string]
+  SpecificIterator2 = ref object of Iterator[int]
+
+
+
+
+# bug #3431
+type
+  Lexer = object
+    buf*: string
+    pos*: int
+    lastchar*: char
+
+  ASTNode = object
+
+method init*(self: var Lexer; buf: string) {.base.} =
+  self.buf = buf
+  self.pos = 0
+  self.lastchar = self.buf[0]
+
+method init*(self: var ASTNode; val: string) =
+  discard
+
+
+
+# bug #3370
+type
+  RefTestA*[T] = ref object of RootObj
+    data*: T
+
+method tester*[S](self: S): bool =
+  true
+
+type
+  RefTestB* = RefTestA[(string, int)]
+
+method tester*(self: RefTestB): bool =
+  true
+
+type
+  RefTestC = RefTestA[string]
+
+method tester*(self: RefTestC): bool =
+  false
+
+
+
+# bug #3468
+type X = ref object of RootObj
+type Y = ref object of RootObj
+
+method draw*(x: X) {.base.} = discard
+method draw*(y: Y) {.base.} = discard
+
+
+
+# bug #3550
+type 
+  BaseClass = ref object of RootObj
+  Class1 = ref object of BaseClass
+  Class2 = ref object of BaseClass
+  
+method test(obj: Class1, obj2: BaseClass) =
+  discard
+
+method test(obj: Class2, obj2: BaseClass) =
+  discard
+  
+var obj1 = Class1()
+var obj2 = Class2()
+
+obj1.test(obj2) 
+obj2.test(obj1)
+
+
+# -------------------------------------------------------
+# issue #16516
+
+type
+  A = ref object of RootObj
+    x: int
+
+  B = ref object of A
+
+method foo(v: sink A, lst: var seq[A]) {.base,locks:0.} =
+  echo "type A"
+  lst.add v
+
+method foo(v: sink B, lst: var seq[A]) =
+  echo "type B"
+  lst.add v
+
+proc main() =
+  let
+    a = A(x: 5)
+    b: A = B(x: 5)
+
+  var lst: seq[A]
+
+  foo(a, lst)
+  foo(b, lst)
+
+main()
+
+block: # bug #20391
+  type Container[T] = ref object of RootRef
+    item: T
+
+  let a = Container[int]()
+
+  doAssert a of Container[int]
+  doAssert not (a of Container[string])
diff --git a/tests/method/tmethod_various.nim b/tests/method/tmethod_various.nim
new file mode 100644
index 000000000..3b64aea8d
--- /dev/null
+++ b/tests/method/tmethod_various.nim
@@ -0,0 +1,79 @@
+discard """
+  matrix: "--mm:arc; --mm:refc"
+  output: '''
+HELLO WORLD!
+'''
+"""
+
+
+
+
+type
+  TNode* {.inheritable.} = object
+  PNode* = ref TNode
+
+  PNodeFoo* = ref object of TNode
+
+  TSomethingElse = object
+  PSomethingElse = ref TSomethingElse
+
+method foo(a: PNode, b: PSomethingElse) {.base.} = discard
+method foo(a: PNodeFoo, b: PSomethingElse) = discard
+
+
+
+
+# tmproto
+type
+  Obj1 {.inheritable.} = ref object
+  Obj2 = ref object of Obj1
+
+method beta(x: Obj1): int {.base.}
+
+proc delta(x: Obj2): int =
+  beta(x)
+
+method beta(x: Obj2): int
+
+proc alpha(x: Obj1): int =
+  beta(x)
+
+method beta(x: Obj1): int = 1
+method beta(x: Obj2): int = 2
+
+proc gamma(x: Obj1): int =
+  beta(x)
+
+doAssert alpha(Obj1()) == 1
+doAssert gamma(Obj1()) == 1
+doAssert alpha(Obj2()) == 2
+doAssert gamma(Obj2()) == 2
+doAssert delta(Obj2()) == 2
+
+
+
+# tsimmeth
+import strutils
+var x = "hello world!".toLowerAscii.toUpperAscii
+x.echo()
+
+
+
+# trecmeth
+# Note: We only compile this to verify that code generation
+# for recursive methods works, no code is being executed
+type Obj = ref object of RootObj
+
+# Mutual recursion
+method alpha(x: Obj) {.base.}
+method beta(x: Obj) {.base.}
+
+method alpha(x: Obj) =
+  beta(x)
+
+method beta(x: Obj) =
+  alpha(x)
+
+# Simple recursion
+method gamma(x: Obj) {.base.} =
+  gamma(x)
diff --git a/tests/method/tmethods_old.nim b/tests/method/tmethods_old.nim
new file mode 100644
index 000000000..d24eb0cc7
--- /dev/null
+++ b/tests/method/tmethods_old.nim
@@ -0,0 +1,12 @@
+discard """
+  matrix: "--mm:arc -d:nimInternalNonVtablesTesting"
+  output: '''
+do nothing
+'''
+"""
+
+# tmethods1
+method somethin(obj: RootObj) {.base.} =
+  echo "do nothing"
+var o: RootObj
+o.somethin()
diff --git a/tests/method/tmultim.nim b/tests/method/tmultim.nim
new file mode 100644
index 000000000..bba4d8c5c
--- /dev/null
+++ b/tests/method/tmultim.nim
@@ -0,0 +1,97 @@
+discard """

+  matrix: "--multimethods:on"

+  output: '''

+collide: unit, thing

+collide: unit, thing

+collide: thing, unit

+collide: thing, thing

+collide: unit, thing |

+collide: unit, thing |

+collide: thing, unit |

+do nothing

+'''

+  joinable: false

+  disabled: true

+"""

+

+

+# tmultim2

+type

+  TThing {.inheritable.} = object

+  TUnit = object of TThing

+    x: int

+  TParticle = object of TThing

+    a, b: int

+

+method collide(a, b: TThing) {.base, inline.} =

+  echo "collide: thing, thing"

+

+method collide(a: TThing, b: TUnit) {.inline.} =

+  echo "collide: thing, unit"

+

+method collide(a: TUnit, b: TThing) {.inline.} =

+  echo "collide: unit, thing"

+

+proc test(a, b: TThing) {.inline.} =

+  collide(a, b)

+

+proc staticCollide(a, b: TThing) {.inline.} =

+  procCall collide(a, b)

+

+var

+  a: TThing

+  b, c: TUnit

+collide(b, c) # ambiguous (unit, thing) or (thing, unit)? -> prefer unit, thing!

+test(b, c)

+collide(a, b)

+staticCollide(a, b)

+

+

+

+# tmultim6

+type

+  Thing {.inheritable.} = object

+  Unit[T] = object of Thing

+    x: T

+  Particle = object of Thing

+    a, b: int

+

+method collide(a, b: Thing) {.base, inline.} =

+  quit "to override!"

+

+method collide[T](a: Thing, b: Unit[T]) {.inline.} =

+  echo "collide: thing, unit |"

+

+method collide[T](a: Unit[T], b: Thing) {.inline.} =

+  echo "collide: unit, thing |"

+

+proc test(a, b: Thing) {.inline.} =

+  collide(a, b)

+

+var

+  aaa: Thing

+  bbb, ccc: Unit[string]

+collide(bbb, Thing(ccc))

+test(bbb, ccc)

+collide(aaa, bbb)

+

+

+

+# tmethods1

+method somethin(obj: RootObj) {.base.} =

+  echo "do nothing"

+

+type

+  TNode* {.inheritable.} = object

+  PNode* = ref TNode

+

+  PNodeFoo* = ref object of TNode

+

+  TSomethingElse = object

+  PSomethingElse = ref TSomethingElse

+

+method foo(a: PNode, b: PSomethingElse) {.base.} = discard

+method foo(a: PNodeFoo, b: PSomethingElse) = discard

+

+var o: RootObj

+o.somethin()

diff --git a/tests/method/tmultimjs.nim b/tests/method/tmultimjs.nim
new file mode 100644
index 000000000..36960f2e1
--- /dev/null
+++ b/tests/method/tmultimjs.nim
@@ -0,0 +1,73 @@
+discard """
+  output: '''
+7
+Hi derived!
+hello
+'''
+  disabled: true
+"""
+
+
+# tmultim1
+type
+  Expression {.inheritable.} = ref object
+  Literal = ref object of Expression
+    x: int
+  PlusExpr = ref object of Expression
+    a, b: Expression
+
+method eval(e: Expression): int {.base.} = quit "to override!"
+method eval(e: Literal): int = return e.x
+method eval(e: PlusExpr): int = return eval(e.a) + eval(e.b)
+
+proc newLit(x: int): Literal =
+  new(result)
+  result.x = x
+
+proc newPlus(a, b: Expression): PlusExpr =
+  new(result)
+  result.a = a
+  result.b = b
+
+echo eval(newPlus(newPlus(newLit(1), newLit(2)), newLit(4))) #OUT 7
+
+
+
+# tmultim3
+import mmultim3
+
+type TBObj* = object of TObj
+
+method test123(a : ref TBObj) =
+    echo("Hi derived!")
+
+var aa: ref TBObj
+new(aa)
+myObj = aa
+testMyObj()
+
+
+
+# tmultim4
+type Test = object of RootObj
+
+method doMethod(a: ref RootObj) {.base, raises: [IoError].} =
+  quit "override"
+
+method doMethod(a: ref Test) =
+  echo "hello"
+  if a == nil:
+    raise newException(IoError, "arg")
+
+proc doProc(a: ref Test) =
+  echo "hello"
+
+proc newTest(): ref Test =
+  new(result)
+
+var s:ref Test = newTest()
+
+#doesn't work
+for z in 1..4:
+  s.doMethod()
+  break
diff --git a/tests/method/tnildispatcher.nim b/tests/method/tnildispatcher.nim
new file mode 100644
index 000000000..219d2b29f
--- /dev/null
+++ b/tests/method/tnildispatcher.nim
@@ -0,0 +1,21 @@
+discard """
+  outputsub: '''Error: unhandled exception: cannot dispatch; dispatcher is nil [NilAccessDefect]'''
+  exitcode: 1
+"""
+# bug #5599
+type
+    Base = ref object of RootObj
+    Derived = ref object of Base
+
+method inner(obj: Base) {.base.} =
+    quit "to override"
+
+method outer(obj: Base) {.base.} =
+    echo "outer"
+    obj.inner()
+
+method inner(obj: Derived) =
+    echo "inner Derived"
+
+var x: Derived
+x.outer()
diff --git a/tests/method/treturn_var_t.nim b/tests/method/treturn_var_t.nim
new file mode 100644
index 000000000..91d982902
--- /dev/null
+++ b/tests/method/treturn_var_t.nim
@@ -0,0 +1,25 @@
+discard """
+  output: '''Inh
+45'''
+"""
+
+type
+  Base = ref object of RootObj
+    field: int
+
+  Inh = ref object of Base
+
+# bug #6777
+method foo(b: Base): var int {.base.} =
+  echo "Base"
+  result = b.field
+
+method foo(b: Inh): var int =
+  echo "Inh"
+  result = b.field
+
+var x: Base
+var y = Inh(field: 45)
+x = y
+echo foo(x)
+
diff --git a/tests/method/tsingle_methods.nim b/tests/method/tsingle_methods.nim
new file mode 100644
index 000000000..b564e7d87
--- /dev/null
+++ b/tests/method/tsingle_methods.nim
@@ -0,0 +1,48 @@
+discard """
+  matrix: "--mm:arc --multimethods:off; --mm:refc --multimethods:off"
+  output: '''base
+base
+base
+base
+base
+base
+'''
+"""
+
+# bug #10912
+
+type
+  X = ref object of RootObj
+
+type
+  A* = ref object of RootObj
+  B* = ref object of A
+  C* = ref object of A
+  D* = ref object of A
+  E* = ref object of A
+  F* = ref object of A
+
+method resolve(self: var X, stmt: A) {.base.} = echo "base"
+
+proc resolveSeq*(self: var X, statements: seq[A]) =
+  for statement in statements:
+    resolve(self, statement)
+
+method resolve(self: var X, stmt: B) =
+  echo "B"
+
+method resolve(self: var X, stmt: D) =
+  echo "D"
+
+method resolve(self: var X, stmt: E) =
+  echo "E"
+
+method resolve(self: var X, stmt: C) =
+  echo "C"
+
+method resolve(self: var X, stmt: F) =
+  echo "F"
+
+var x = X()
+var a = @[A(), B(), C(), D(), E(), F()]
+resolveSeq(x, a)
diff --git a/tests/method/tvtable.nim b/tests/method/tvtable.nim
new file mode 100644
index 000000000..a1b33d6b7
--- /dev/null
+++ b/tests/method/tvtable.nim
@@ -0,0 +1,24 @@
+discard """

+  targets: "c cpp"

+"""

+

+type FooBase = ref object of RootObj

+  dummy: int

+type Foo = ref object of FooBase

+  value : float32

+type Foo2 = ref object of Foo

+  change : float32

+method bar(x: FooBase, a: float32) {.base.} =

+  discard

+method bar(x: Foo, a: float32)  =

+  x.value += a

+method bar(x: Foo2, a: float32)  =

+  x.value += a

+

+

+proc test() =

+  var x = new Foo2

+  x.bar(2.3)

+  doAssert x.value <= 2.3

+

+test()
\ No newline at end of file