privateAccess now works with ref | ptr (#17760)
This commit is contained in:
parent
d6c8efa5d4
commit
0a10af5a2c
8 changed files with 149 additions and 15 deletions
|
|
@ -578,9 +578,9 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
|
||||||
n[0].sym.magic = mSubU
|
n[0].sym.magic = mSubU
|
||||||
result = n
|
result = n
|
||||||
of mPrivateAccess:
|
of mPrivateAccess:
|
||||||
let sym = n[1].typ[0].sym
|
var t = n[1].typ[0]
|
||||||
assert sym != nil
|
if t.kind in {tyRef, tyPtr}: t = t[0]
|
||||||
c.currentScope.allowPrivateAccess.add sym
|
c.currentScope.allowPrivateAccess.add t.sym
|
||||||
result = newNodeIT(nkEmpty, n.info, getSysType(c.graph, n.info, tyVoid))
|
result = newNodeIT(nkEmpty, n.info, getSysType(c.graph, n.info, tyVoid))
|
||||||
else:
|
else:
|
||||||
result = n
|
result = n
|
||||||
|
|
|
||||||
|
|
@ -258,7 +258,9 @@ proc fieldVisible*(c: PContext, f: PSym): bool {.inline.} =
|
||||||
for module in c.friendModules:
|
for module in c.friendModules:
|
||||||
if fmoduleId == module.id: return true
|
if fmoduleId == module.id: return true
|
||||||
if f.kind == skField:
|
if f.kind == skField:
|
||||||
let symObj = f.owner
|
var symObj = f.owner
|
||||||
|
if symObj.typ.kind in {tyRef, tyPtr}:
|
||||||
|
symObj = symObj.typ[0].sym
|
||||||
for scope in allScopes(c.currentScope):
|
for scope in allScopes(c.currentScope):
|
||||||
for sym in scope.allowPrivateAccess:
|
for sym in scope.allowPrivateAccess:
|
||||||
if symObj.id == sym.id: return true
|
if symObj.id == sym.id: return true
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ when defined(nimImportutilsExample):
|
||||||
x1: int # private
|
x1: int # private
|
||||||
proc initFoo*(): auto = Foo()
|
proc initFoo*(): auto = Foo()
|
||||||
|
|
||||||
proc privateAccess*(t: typedesc) {.magic: "PrivateAccess".} =
|
proc privateAccess*(t: typedesc[object|ref|ptr]) {.magic: "PrivateAccess".} =
|
||||||
## Enables access to private fields of `t` in current scope.
|
## Enables access to private fields of `t` in current scope.
|
||||||
runnableExamples("-d:nimImportutilsExample"):
|
runnableExamples("-d:nimImportutilsExample"):
|
||||||
# here we're importing a module containing:
|
# here we're importing a module containing:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import std/private/miscdollars
|
import std/private/miscdollars
|
||||||
from std/os import getEnv
|
from std/os import getEnv
|
||||||
|
import std/[macros, genasts]
|
||||||
|
|
||||||
template flakyAssert*(cond: untyped, msg = "", notifySuccess = true) =
|
template flakyAssert*(cond: untyped, msg = "", notifySuccess = true) =
|
||||||
## API to deal with flaky or failing tests. This avoids disabling entire tests
|
## API to deal with flaky or failing tests. This avoids disabling entire tests
|
||||||
|
|
@ -89,3 +90,22 @@ template reject*(a) =
|
||||||
template disableVm*(body) =
|
template disableVm*(body) =
|
||||||
when nimvm: discard
|
when nimvm: discard
|
||||||
else: body
|
else: body
|
||||||
|
|
||||||
|
template typeOrVoid[T](a: T): type =
|
||||||
|
# FACTOR with asyncjs.typeOrVoid
|
||||||
|
T
|
||||||
|
|
||||||
|
macro assertAll*(body) =
|
||||||
|
## works in VM, unlike `check`, `require`
|
||||||
|
runnableExamples:
|
||||||
|
assertAll:
|
||||||
|
1+1 == 2
|
||||||
|
var a = @[1, 2] # statements work
|
||||||
|
a.len == 2
|
||||||
|
# remove this once these support VM, pending #10129 (closed but not yet fixed)
|
||||||
|
result = newStmtList()
|
||||||
|
for a in body:
|
||||||
|
result.add genAst(a) do:
|
||||||
|
# better than: `when not compiles(typeof(a)):`
|
||||||
|
when typeOrVoid(a) is void: a
|
||||||
|
else: doAssert a
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ doAssert m.m3p1 == 2
|
||||||
## field access
|
## field access
|
||||||
import std/importutils
|
import std/importutils
|
||||||
privateAccess(Foo5)
|
privateAccess(Foo5)
|
||||||
# var x = Foo5(z1: "foo", z2: m.kg1)
|
var x = Foo5(z1: "foo", z2: m.kg1)
|
||||||
# doAssert x.z1 == "foo"
|
doAssert x.z1 == "foo"
|
||||||
|
|
||||||
var f0: Foo5
|
var f0: Foo5
|
||||||
f0.z3 = 3
|
f0.z3 = 3
|
||||||
|
|
|
||||||
17
tests/stdlib/mimportutils.nim
Normal file
17
tests/stdlib/mimportutils.nim
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
type
|
||||||
|
A* = object
|
||||||
|
a0*: int
|
||||||
|
ha1: float
|
||||||
|
B = object
|
||||||
|
b0*: int
|
||||||
|
hb1: float
|
||||||
|
C* = ref object
|
||||||
|
c0: int
|
||||||
|
hc1: float
|
||||||
|
D* = ptr object
|
||||||
|
d0: int
|
||||||
|
hd1: float
|
||||||
|
PA* = ref A
|
||||||
|
PtA* = ptr A
|
||||||
|
|
||||||
|
proc initB*(): B = B()
|
||||||
82
tests/stdlib/timportutils.nim
Normal file
82
tests/stdlib/timportutils.nim
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
import std/importutils
|
||||||
|
import stdtest/testutils
|
||||||
|
import mimportutils
|
||||||
|
|
||||||
|
template main =
|
||||||
|
block: # privateAccess
|
||||||
|
assertAll:
|
||||||
|
var a: A
|
||||||
|
var b = initB() # B is private
|
||||||
|
compiles(a.a0)
|
||||||
|
compiles(b.b0)
|
||||||
|
not compiles(a.ha1)
|
||||||
|
not compiles(b.hb1)
|
||||||
|
|
||||||
|
block:
|
||||||
|
assertAll:
|
||||||
|
privateAccess A
|
||||||
|
compiles(a.ha1)
|
||||||
|
a.ha1 == 0.0
|
||||||
|
not compiles(a.hb1)
|
||||||
|
privateAccess b.typeof
|
||||||
|
b.hb1 = 3
|
||||||
|
type B2 = b.typeof
|
||||||
|
let b2 = B2(b0: 4, hb1: 5)
|
||||||
|
b.hb1 == 3
|
||||||
|
b2 == B2(b0: 4, hb1: 5)
|
||||||
|
|
||||||
|
assertAll:
|
||||||
|
not compiles(a.ha1)
|
||||||
|
not compiles(b.hb1)
|
||||||
|
|
||||||
|
block:
|
||||||
|
assertAll:
|
||||||
|
not compiles(C(c0: 1, hc1: 2))
|
||||||
|
privateAccess C
|
||||||
|
let c = C(c0: 1, hc1: 2)
|
||||||
|
c.hc1 == 2
|
||||||
|
|
||||||
|
block:
|
||||||
|
assertAll:
|
||||||
|
privateAccess PA
|
||||||
|
var pa = PA(a0: 1, ha1: 2)
|
||||||
|
pa.ha1 == 2
|
||||||
|
pa.ha1 = 3
|
||||||
|
pa.ha1 == 3
|
||||||
|
|
||||||
|
block:
|
||||||
|
assertAll:
|
||||||
|
var a = A(a0: 1)
|
||||||
|
var a2 = a.addr
|
||||||
|
not compiles(a2.ha1)
|
||||||
|
privateAccess PtA
|
||||||
|
a2.type is PtA
|
||||||
|
a2.ha1 = 2
|
||||||
|
a2.ha1 == 2
|
||||||
|
a.ha1 = 3
|
||||||
|
a2.ha1 == 3
|
||||||
|
|
||||||
|
block:
|
||||||
|
disableVm:
|
||||||
|
assertAll:
|
||||||
|
var a = A.create()
|
||||||
|
defer: dealloc(a)
|
||||||
|
a is PtA
|
||||||
|
a.typeof is PtA
|
||||||
|
not compiles(a.ha1)
|
||||||
|
privateAccess a.typeof
|
||||||
|
a.ha1 = 2
|
||||||
|
a.ha1 == 2
|
||||||
|
a[].ha1 = 3
|
||||||
|
a.ha1 == 3
|
||||||
|
|
||||||
|
block:
|
||||||
|
disableVm:
|
||||||
|
assertAll:
|
||||||
|
var a = A.create()
|
||||||
|
defer: dealloc(a)
|
||||||
|
privateAccess PtA
|
||||||
|
a.ha1 == 0
|
||||||
|
|
||||||
|
static: main()
|
||||||
|
main()
|
||||||
|
|
@ -1,11 +1,24 @@
|
||||||
import stdtest/testutils
|
import stdtest/testutils
|
||||||
|
|
||||||
block: # greedyOrderedSubsetLines
|
block: # assertAll
|
||||||
doAssert greedyOrderedSubsetLines("a1\na3", "a0\na1\na2\na3\na4")
|
assertAll:
|
||||||
doAssert not greedyOrderedSubsetLines("a3\na1", "a0\na1\na2\na3\na4") # out of order
|
1+1 == 2
|
||||||
doAssert not greedyOrderedSubsetLines("a1\na5", "a0\na1\na2\na3\na4") # a5 not in lhs
|
var a = 3
|
||||||
|
a == 3
|
||||||
|
|
||||||
doAssert not greedyOrderedSubsetLines("a1\na5", "a0\na1\na2\na3\na4\nprefix:a5")
|
doAssertRaises(AssertionDefect):
|
||||||
doAssert not greedyOrderedSubsetLines("a1\na5", "a0\na1\na2\na3\na4\na5:suffix")
|
assertAll:
|
||||||
doAssert not greedyOrderedSubsetLines("a5", "a0\na1\na2\na3\na4\nprefix:a5")
|
1+1 == 2
|
||||||
doAssert not greedyOrderedSubsetLines("a5", "a0\na1\na2\na3\na4\na5:suffix")
|
var a = 3
|
||||||
|
a == 4
|
||||||
|
|
||||||
|
block: # greedyOrderedSubsetLines
|
||||||
|
assertAll:
|
||||||
|
greedyOrderedSubsetLines("a1\na3", "a0\na1\na2\na3\na4")
|
||||||
|
not greedyOrderedSubsetLines("a3\na1", "a0\na1\na2\na3\na4") # out of order
|
||||||
|
not greedyOrderedSubsetLines("a1\na5", "a0\na1\na2\na3\na4") # a5 not in lhs
|
||||||
|
|
||||||
|
not greedyOrderedSubsetLines("a1\na5", "a0\na1\na2\na3\na4\nprefix:a5")
|
||||||
|
not greedyOrderedSubsetLines("a1\na5", "a0\na1\na2\na3\na4\na5:suffix")
|
||||||
|
not greedyOrderedSubsetLines("a5", "a0\na1\na2\na3\na4\nprefix:a5")
|
||||||
|
not greedyOrderedSubsetLines("a5", "a0\na1\na2\na3\na4\na5:suffix")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue