From 5a6775831ce8365f241ed9bedb2f8cb692ba4bff Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Tue, 27 Aug 2019 17:51:54 -0700 Subject: [PATCH] add tests from D20190825T173945 --- tests/magics/mresolve_overloads.nim | 8 ++ tests/magics/mresolves.nim | 45 ++++++++ tests/magics/tresolve_overloads.nim | 165 ++++++++++++++++++++++++++++ 3 files changed, 218 insertions(+) create mode 100644 tests/magics/mresolve_overloads.nim create mode 100644 tests/magics/mresolves.nim create mode 100644 tests/magics/tresolve_overloads.nim diff --git a/tests/magics/mresolve_overloads.nim b/tests/magics/mresolve_overloads.nim new file mode 100644 index 0000000000000..ae0f559692444 --- /dev/null +++ b/tests/magics/mresolve_overloads.nim @@ -0,0 +1,8 @@ +let foo1* = [1,2] ## c1 +var foo2* = "asdf" ## c2 +const foo3* = 'a' ## c3 + +proc `@@@`*(a: int) = discard +proc `@@@`*(a: float) = discard +proc `@@@`*[T: Ordinal](a: T) = discard + diff --git a/tests/magics/mresolves.nim b/tests/magics/mresolves.nim new file mode 100644 index 0000000000000..eb1837f607402 --- /dev/null +++ b/tests/magics/mresolves.nim @@ -0,0 +1,45 @@ +import std/macros + +macro overloadExistsImpl(x: typed): bool = + newLit(x != nil) + +template overloadExists*(a: untyped): bool = + overloadExistsImpl(resolveSymbol(a)) + +type InstantiationInfo = type(instantiationInfo()) + +proc toStr(info: InstantiationInfo | LineInfo): string = + const offset = 1 + result = info.filename & ":" & $info.line & ":" & $(info.column + offset) + +proc inspectImpl*(s: var string, a: NimNode, resolveLet: bool) = + var a = a + if resolveLet: + a = a.getImpl + a = a[2] + case a.kind + of nnkClosedSymChoice: + s.add "closedSymChoice:" + for ai in a: + s.add "\n " + inspectImpl(s, ai, false) + of nnkSym: + var a2 = a.getImpl + const callables = {nnkProcDef, nnkMethodDef, nnkConverterDef, nnkMacroDef, nnkTemplateDef, nnkIteratorDef} + if a2.kind in callables: + let a20=a2 + a2 = newTree(a20.kind) + for i, ai in a20: + a2.add if i notin [6]: ai else: newEmptyNode() + s.add a2.lineInfoObj.toStr & " " & a2.repr + else: error($a.kind, a) + +macro inspect*(a: typed, resolveLet: static bool = false): untyped = + var a = a + if a.kind == nnkTupleConstr: + a = a[0] + var s: string + s.add a.lineInfoObj.toStr & ": " + s.add a.repr & " = " + inspectImpl(s, a, resolveLet) + echo s diff --git a/tests/magics/tresolve_overloads.nim b/tests/magics/tresolve_overloads.nim new file mode 100644 index 0000000000000..a8d53ead2dd25 --- /dev/null +++ b/tests/magics/tresolve_overloads.nim @@ -0,0 +1,165 @@ +#[ +D20190825T173945 +]# + +import ./mresolves + +template bail() = static: doAssert false + +proc funDecl1(a: int) {.importc.} +proc funDecl2(a: int) + +proc fun(a: int) = discard + +template fun2(a = 0) = bail() +template fun3() = bail() + +proc fun4(a: float) = discard + +proc fun4[T](a: T) = + static: echo "in fun4" + bail() + +macro fun5(a: typed): untyped = discard +macro fun6(a: untyped): untyped = discard +iterator fun7(a: int): auto = yield 1 + +proc fun8(a: int): auto = (a, "int") +proc fun8(a: float): tuple = (a,"float") +template fun8(a: string) = discard +template fun8(a: char = 'x') = discard +template fun8() = discard +macro fun8(b = 1'u8): untyped = discard +macro fun8(c: static bool): untyped = discard + +proc fun8(d: var int) = d.inc + +proc main()= + static: + doAssert overloadExists(fun4(1)) + doAssert not compiles(fun4(1)) + doAssert overloadExists(fun4(1)) + doAssert overloadExists(fun4(1.2)) + doAssert not overloadExists(fun4()) + # doAssert not overloadExists(nonexistant(1)) # should we error with `Error: undeclared identifier: 'nonexistant'` ? A: probly should just return false, eg: imagine for: ` 1 @ 2` + + doAssert overloadExists(funDecl1(1)) + doAssert not overloadExists(funDecl1(1.0)) + doAssert overloadExists(funDecl2(1)) + + doAssert overloadExists(fun(1)) + doAssert overloadExists(1+1) + doAssert not overloadExists('a'+1.2) + + doAssert not overloadExists(fun(1.1)) + doAssert not overloadExists(fun(1, 2)) + doAssert overloadExists(fun2()) + doAssert overloadExists(fun2(1)) + doAssert overloadExists(fun3()) + doAssert not overloadExists(fun3(1)) + + # subtlety: if arguments for a `typed` formal param are not well typed, + # we error instead of return false + doAssert not compiles overloadExists(fun5(1 + 'a')) + + doAssert overloadExists(fun5(1 + 1)) + doAssert not overloadExists(fun5(1 + 1, 2)) + doAssert overloadExists(fun6(1 + 'a')) + doAssert not overloadExists(fun6(1 + 'a', 2)) + doAssert overloadExists(fun7(1)) + doAssert not overloadExists(fun7()) + + doAssert resolveSymbol(fun8(1))(3) == fun8(3) + inspect resolveSymbol(fun8) + + inspect resolveSymbol(fun7) + inspect resolveSymbol(fun8(1)) + inspect resolveSymbol(fun8(1.2)) + inspect resolveSymbol(fun8("asdf")) + inspect resolveSymbol(fun8('a')) + doAssert compiles(resolveSymbol(fun8('a'))) + doAssert not compiles(resolveSymbol(fun8())) # correctly would give ambiguous error + inspect resolveSymbol(fun8(b = 1)) + inspect resolveSymbol(fun8(c = false)) + inspect resolveSymbol(1.1 / 2.0) + + block: + var c1 = false + doAssert not overloadExists(fun8(c = c1)) + const c2 = false + doAssert overloadExists(fun8(c = c2)) + var c3 = 10 + doAssert overloadExists(fun8(d = c3)) + doAssert c3 == 10 + resolveSymbol(fun8(d = c3))(d = c3) + doAssert c3 == 11 + let t = resolveSymbol(fun8(d = c3)) + doAssert type(t) is proc + t(d = c3) + doAssert c3 == 12 + + block: + var z = 10 + proc fun9(z0: int) = z+=z0 + proc fun9(z0: float) = doAssert false + let t = resolveSymbol(fun9(12)) + # can't work with `const t = fun9`: invalid type for const + doAssert type(t) is proc + t(3) + doAssert z == 10+3 + inspect resolveSymbol(fun9(12)) + inspect(resolveSymbol(t), resolveLet=true) + +import std/strutils +import std/macros +import std/macros as macrosAlias +import ./mresolve_overloads + +proc main2()= + block: + inspect resolveSymbol(`@@@`) + + let t = resolveSymbol toUpper("asdf") + inspect resolveSymbol(t), resolveLet=true + doAssert t("asdf") == "ASDF" + let t2 = resolveSymbol strutils.toUpper("asdf") + inspect resolveSymbol(t2), resolveLet=true + doAssert t2("asdf") == "ASDF" + + inspect resolveSymbol(strutils.toUpper) + inspect resolveSymbol(strutils.`toUpper`) + inspect resolveSymbol(`toUpper`) + # overloaded + inspect resolveSymbol(`$`) + inspect resolveSymbol(system.`$`) + + doAssert compiles resolveSymbol(system.compiles) + inspect resolveSymbol(system.compiles) + doAssert not compiles resolveSymbol(system.nonexistant) + doAssert not compiles resolveSymbol(nonexistant) + + block: + template bar1(): untyped = 12 + inspect resolveSymbol(bar1) + inspect resolveSymbol(currentSourcePath) + inspect resolveSymbol(system.currentSourcePath) + doAssert resolveSymbol(system.currentSourcePath)() == currentSourcePath() + inspect resolveSymbol(system.uint16) + inspect resolveSymbol(system.cint) + inspect resolveSymbol(cint) + inspect resolveSymbol(system.off) + inspect resolveSymbol(newLit(true)) + inspect resolveSymbol(foo1) + inspect resolveSymbol(foo2) + inspect resolveSymbol(foo3) + inspect resolveSymbol(mresolve_overloads.foo3) + inspect resolveSymbol(macros.nnkCallKinds) + + ## module + inspect resolveSymbol(macros) + inspect resolveSymbol(macrosAlias) + +proc funDecl2(a: int) = discard + +main() +main2()