src/pylib/pysugar/stmt/class

Search:
Group by:
Source   Edit  

Procs

proc classImpl(obj, body: NimNode): NimNode {....raises: [Exception],
    tags: [RootEffect], forbids: [].}

minic Python's class.

support def for method with nested def/class supported and super(...).method

NOTE:

Method Overwrite

Now the implement assume each def in each child class overwrite parent class's def, which is surely not always true,

What's more, it will be false in some less-noted cases:

class O:
def f(self): return 1
class O1(O):
def f(self): return 1.0
The above code will cause Warning: use {.base.} for base methods; baseless methods are deprecated [UseBase]

as the rettype of previous one is int, while the latter is float, thus no override and no dynamic dispatch is performed.

super function

Now support super([self[,SubCls]]).f([arg,...])

However, only support the one usage above.

That's, neither a=super() nor super().a is supported

For the precious one, as now super is implemented via Nim's procCall, it's not easy to bind super()(aka. a SupCls instance) to a variable.

For the latter one, as Nim doesn't allow override SupCls's attr (lead to a compile-error), so if wantting the attr inherited from SupCls, just write it as-is (e.g. self.a) (Technologically, it can be implemented via std/macros owner)

Source   Edit  
proc recReplaceSuperCall(n: NimNode; defSupCls: NimNode; start = 0): NimNode {.
    ...raises: [], tags: [], forbids: [].}

Recursively maps super(...).f(...) to procCall(<SuperClass>(self).f(...))

The AST map:

Call
DotExpr
Call
  Ident "super"
  [Ident "self"]
  [<SuperClass>]
Ident "f"
<args>

|
|
v

Command
Ident "procCall"
Call
DotExpr
  Call
    <SuperClass>
    Ident "self"
  Ident "f"

Example:

import std/[macros, strutils]
macro checkSupSub(resStr: static string; b) =
  let res = recReplaceSuperCall(b, ident"SupCls")
  assert resStr == repr(res).strip(), repr(res)
  result = newStmtList()
checkSupSub("procCall(SupCls(self).f())"):
  super().f()
checkSupSub("procCall(SS(self).f(a, b))"):
  super(self, SS).f(a, b)
checkSupSub("a = procCall(SupCls(self).f(a, b))"):
  a = super().f(a, b)
checkSupSub("a = procCall(SupCls(self).f(procCall(SupCls(self).m()), b))"):
  a = super().f(super().m(), b)
checkSupSub("echo(1)"): echo(1)

# NOTE: the following is not supported, so left unchanged
checkSupSub("super()"): super()
checkSupSub("super().a"): super().a
Source   Edit