privateAccess now works with ref | ptr (#17760)

This commit is contained in:
Timothee Cour
2021-04-18 15:15:58 -07:00
committed by GitHub
parent d6c8efa5d4
commit 0a10af5a2c
8 changed files with 149 additions and 15 deletions

View File

@@ -578,9 +578,9 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
n[0].sym.magic = mSubU
result = n
of mPrivateAccess:
let sym = n[1].typ[0].sym
assert sym != nil
c.currentScope.allowPrivateAccess.add sym
var t = n[1].typ[0]
if t.kind in {tyRef, tyPtr}: t = t[0]
c.currentScope.allowPrivateAccess.add t.sym
result = newNodeIT(nkEmpty, n.info, getSysType(c.graph, n.info, tyVoid))
else:
result = n

View File

@@ -258,7 +258,9 @@ proc fieldVisible*(c: PContext, f: PSym): bool {.inline.} =
for module in c.friendModules:
if fmoduleId == module.id: return true
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 sym in scope.allowPrivateAccess:
if symObj.id == sym.id: return true

View File

@@ -17,7 +17,7 @@ when defined(nimImportutilsExample):
x1: int # private
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.
runnableExamples("-d:nimImportutilsExample"):
# here we're importing a module containing:

View File

@@ -1,5 +1,6 @@
import std/private/miscdollars
from std/os import getEnv
import std/[macros, genasts]
template flakyAssert*(cond: untyped, msg = "", notifySuccess = true) =
## API to deal with flaky or failing tests. This avoids disabling entire tests
@@ -89,3 +90,22 @@ template reject*(a) =
template disableVm*(body) =
when nimvm: discard
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

View File

@@ -10,8 +10,8 @@ doAssert m.m3p1 == 2
## field access
import std/importutils
privateAccess(Foo5)
# var x = Foo5(z1: "foo", z2: m.kg1)
# doAssert x.z1 == "foo"
var x = Foo5(z1: "foo", z2: m.kg1)
doAssert x.z1 == "foo"
var f0: Foo5
f0.z3 = 3

View 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()

View 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()

View File

@@ -1,11 +1,24 @@
import stdtest/testutils
block: # greedyOrderedSubsetLines
doAssert greedyOrderedSubsetLines("a1\na3", "a0\na1\na2\na3\na4")
doAssert not greedyOrderedSubsetLines("a3\na1", "a0\na1\na2\na3\na4") # out of order
doAssert not greedyOrderedSubsetLines("a1\na5", "a0\na1\na2\na3\na4") # a5 not in lhs
block: # assertAll
assertAll:
1+1 == 2
var a = 3
a == 3
doAssert not greedyOrderedSubsetLines("a1\na5", "a0\na1\na2\na3\na4\nprefix:a5")
doAssert not greedyOrderedSubsetLines("a1\na5", "a0\na1\na2\na3\na4\na5:suffix")
doAssert not greedyOrderedSubsetLines("a5", "a0\na1\na2\na3\na4\nprefix:a5")
doAssert not greedyOrderedSubsetLines("a5", "a0\na1\na2\na3\na4\na5:suffix")
doAssertRaises(AssertionDefect):
assertAll:
1+1 == 2
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")