deprecate the .this pragma
This commit is contained in:
parent
babd31360a
commit
b4e5c9d075
5 changed files with 48 additions and 51 deletions
|
|
@ -170,6 +170,10 @@
|
||||||
- Nim now supports ``except`` clause in the export statement.
|
- Nim now supports ``except`` clause in the export statement.
|
||||||
|
|
||||||
- Range float types, example ``range[0.0 .. Inf]``. More details in language manual.
|
- Range float types, example ``range[0.0 .. Inf]``. More details in language manual.
|
||||||
|
- The ``{.this.}`` pragma has been deprecated. It never worked within generics and
|
||||||
|
we found the resulting code harder to read than the more explicit ``obj.field``
|
||||||
|
syntax.
|
||||||
|
|
||||||
|
|
||||||
### Tool changes
|
### Tool changes
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,14 +30,7 @@ type
|
||||||
wordCounter: int
|
wordCounter: int
|
||||||
idAnon*, idDelegator*, emptyIdent*: PIdent
|
idAnon*, idDelegator*, emptyIdent*: PIdent
|
||||||
|
|
||||||
when false:
|
proc resetIdentCache*() = discard
|
||||||
var
|
|
||||||
legacy: IdentCache
|
|
||||||
|
|
||||||
proc resetIdentCache*() =
|
|
||||||
when false:
|
|
||||||
for i in low(legacy.buckets)..high(legacy.buckets):
|
|
||||||
legacy.buckets[i] = nil
|
|
||||||
|
|
||||||
proc cmpIgnoreStyle*(a, b: cstring, blen: int): int =
|
proc cmpIgnoreStyle*(a, b: cstring, blen: int): int =
|
||||||
if a[0] != b[0]: return 1
|
if a[0] != b[0]: return 1
|
||||||
|
|
@ -73,11 +66,9 @@ proc cmpExact(a, b: cstring, blen: int): int =
|
||||||
if result == 0:
|
if result == 0:
|
||||||
if a[i] != '\0': result = 1
|
if a[i] != '\0': result = 1
|
||||||
|
|
||||||
{.this: self.}
|
proc getIdent*(ic: IdentCache; identifier: cstring, length: int, h: Hash): PIdent =
|
||||||
|
var idx = h and high(ic.buckets)
|
||||||
proc getIdent*(self: IdentCache; identifier: cstring, length: int, h: Hash): PIdent =
|
result = ic.buckets[idx]
|
||||||
var idx = h and high(buckets)
|
|
||||||
result = buckets[idx]
|
|
||||||
var last: PIdent = nil
|
var last: PIdent = nil
|
||||||
var id = 0
|
var id = 0
|
||||||
while result != nil:
|
while result != nil:
|
||||||
|
|
@ -85,8 +76,8 @@ proc getIdent*(self: IdentCache; identifier: cstring, length: int, h: Hash): PId
|
||||||
if last != nil:
|
if last != nil:
|
||||||
# make access to last looked up identifier faster:
|
# make access to last looked up identifier faster:
|
||||||
last.next = result.next
|
last.next = result.next
|
||||||
result.next = buckets[idx]
|
result.next = ic.buckets[idx]
|
||||||
buckets[idx] = result
|
ic.buckets[idx] = result
|
||||||
return
|
return
|
||||||
elif cmpIgnoreStyle(cstring(result.s), identifier, length) == 0:
|
elif cmpIgnoreStyle(cstring(result.s), identifier, length) == 0:
|
||||||
assert((id == 0) or (id == result.id))
|
assert((id == 0) or (id == result.id))
|
||||||
|
|
@ -97,20 +88,20 @@ proc getIdent*(self: IdentCache; identifier: cstring, length: int, h: Hash): PId
|
||||||
result.h = h
|
result.h = h
|
||||||
result.s = newString(length)
|
result.s = newString(length)
|
||||||
for i in countup(0, length - 1): result.s[i] = identifier[i]
|
for i in countup(0, length - 1): result.s[i] = identifier[i]
|
||||||
result.next = buckets[idx]
|
result.next = ic.buckets[idx]
|
||||||
buckets[idx] = result
|
ic.buckets[idx] = result
|
||||||
if id == 0:
|
if id == 0:
|
||||||
inc(wordCounter)
|
inc(ic.wordCounter)
|
||||||
result.id = -wordCounter
|
result.id = -ic.wordCounter
|
||||||
else:
|
else:
|
||||||
result.id = id
|
result.id = id
|
||||||
|
|
||||||
proc getIdent*(self: IdentCache; identifier: string): PIdent =
|
proc getIdent*(ic: IdentCache; identifier: string): PIdent =
|
||||||
result = getIdent(cstring(identifier), len(identifier),
|
result = getIdent(ic, cstring(identifier), len(identifier),
|
||||||
hashIgnoreStyle(identifier))
|
hashIgnoreStyle(identifier))
|
||||||
|
|
||||||
proc getIdent*(self: IdentCache; identifier: string, h: Hash): PIdent =
|
proc getIdent*(ic: IdentCache; identifier: string, h: Hash): PIdent =
|
||||||
result = getIdent(cstring(identifier), len(identifier), h)
|
result = getIdent(ic, cstring(identifier), len(identifier), h)
|
||||||
|
|
||||||
proc newIdentCache*(): IdentCache =
|
proc newIdentCache*(): IdentCache =
|
||||||
result = IdentCache()
|
result = IdentCache()
|
||||||
|
|
|
||||||
|
|
@ -65,10 +65,8 @@ type
|
||||||
|
|
||||||
proc hash*(x: FileIndex): Hash {.borrow.}
|
proc hash*(x: FileIndex): Hash {.borrow.}
|
||||||
|
|
||||||
{.this: g.}
|
|
||||||
|
|
||||||
proc stopCompile*(g: ModuleGraph): bool {.inline.} =
|
proc stopCompile*(g: ModuleGraph): bool {.inline.} =
|
||||||
result = doStopCompile != nil and doStopCompile()
|
result = g.doStopCompile != nil and g.doStopCompile()
|
||||||
|
|
||||||
proc createMagic*(g: ModuleGraph; name: string, m: TMagic): PSym =
|
proc createMagic*(g: ModuleGraph; name: string, m: TMagic): PSym =
|
||||||
result = newSym(skProc, getIdent(g.cache, name), nil, unknownLineInfo(), {})
|
result = newSym(skProc, getIdent(g.cache, name), nil, unknownLineInfo(), {})
|
||||||
|
|
@ -98,44 +96,44 @@ proc newModuleGraph*(cache: IdentCache; config: ConfigRef): ModuleGraph =
|
||||||
result.cacheTables = initTable[string, BTree[string, PNode]]()
|
result.cacheTables = initTable[string, BTree[string, PNode]]()
|
||||||
|
|
||||||
proc resetAllModules*(g: ModuleGraph) =
|
proc resetAllModules*(g: ModuleGraph) =
|
||||||
initStrTable(packageSyms)
|
initStrTable(g.packageSyms)
|
||||||
deps = initIntSet()
|
g.deps = initIntSet()
|
||||||
modules = @[]
|
g.modules = @[]
|
||||||
importStack = @[]
|
g.importStack = @[]
|
||||||
inclToMod = initTable[FileIndex, FileIndex]()
|
g.inclToMod = initTable[FileIndex, FileIndex]()
|
||||||
usageSym = nil
|
g.usageSym = nil
|
||||||
owners = @[]
|
g.owners = @[]
|
||||||
methods = @[]
|
g.methods = @[]
|
||||||
initStrTable(compilerprocs)
|
initStrTable(g.compilerprocs)
|
||||||
initStrTable(exposed)
|
initStrTable(g.exposed)
|
||||||
|
|
||||||
proc getModule*(g: ModuleGraph; fileIdx: FileIndex): PSym =
|
proc getModule*(g: ModuleGraph; fileIdx: FileIndex): PSym =
|
||||||
if fileIdx.int32 >= 0 and fileIdx.int32 < modules.len:
|
if fileIdx.int32 >= 0 and fileIdx.int32 < g.modules.len:
|
||||||
result = modules[fileIdx.int32]
|
result = g.modules[fileIdx.int32]
|
||||||
|
|
||||||
proc dependsOn(a, b: int): int {.inline.} = (a shl 15) + b
|
proc dependsOn(a, b: int): int {.inline.} = (a shl 15) + b
|
||||||
|
|
||||||
proc addDep*(g: ModuleGraph; m: PSym, dep: FileIndex) =
|
proc addDep*(g: ModuleGraph; m: PSym, dep: FileIndex) =
|
||||||
assert m.position == m.info.fileIndex.int32
|
assert m.position == m.info.fileIndex.int32
|
||||||
addModuleDep(g.incr, g.config, m.info.fileIndex, dep, isIncludeFile = false)
|
addModuleDep(g.incr, g.config, m.info.fileIndex, dep, isIncludeFile = false)
|
||||||
if suggestMode:
|
if g.suggestMode:
|
||||||
deps.incl m.position.dependsOn(dep.int)
|
g.deps.incl m.position.dependsOn(dep.int)
|
||||||
# we compute the transitive closure later when quering the graph lazily.
|
# we compute the transitive closure later when quering the graph lazily.
|
||||||
# this improves efficiency quite a lot:
|
# this improves efficiency quite a lot:
|
||||||
#invalidTransitiveClosure = true
|
#invalidTransitiveClosure = true
|
||||||
|
|
||||||
proc addIncludeDep*(g: ModuleGraph; module, includeFile: FileIndex) =
|
proc addIncludeDep*(g: ModuleGraph; module, includeFile: FileIndex) =
|
||||||
addModuleDep(g.incr, g.config, module, includeFile, isIncludeFile = true)
|
addModuleDep(g.incr, g.config, module, includeFile, isIncludeFile = true)
|
||||||
discard hasKeyOrPut(inclToMod, includeFile, module)
|
discard hasKeyOrPut(g.inclToMod, includeFile, module)
|
||||||
|
|
||||||
proc parentModule*(g: ModuleGraph; fileIdx: FileIndex): FileIndex =
|
proc parentModule*(g: ModuleGraph; fileIdx: FileIndex): FileIndex =
|
||||||
## returns 'fileIdx' if the file belonging to this index is
|
## returns 'fileIdx' if the file belonging to this index is
|
||||||
## directly used as a module or else the module that first
|
## directly used as a module or else the module that first
|
||||||
## references this include file.
|
## references this include file.
|
||||||
if fileIdx.int32 >= 0 and fileIdx.int32 < modules.len and modules[fileIdx.int32] != nil:
|
if fileIdx.int32 >= 0 and fileIdx.int32 < g.modules.len and g.modules[fileIdx.int32] != nil:
|
||||||
result = fileIdx
|
result = fileIdx
|
||||||
else:
|
else:
|
||||||
result = inclToMod.getOrDefault(fileIdx)
|
result = g.inclToMod.getOrDefault(fileIdx)
|
||||||
|
|
||||||
proc transitiveClosure(g: var IntSet; n: int) =
|
proc transitiveClosure(g: var IntSet; n: int) =
|
||||||
# warshall's algorithm
|
# warshall's algorithm
|
||||||
|
|
@ -147,22 +145,22 @@ proc transitiveClosure(g: var IntSet; n: int) =
|
||||||
g.incl i.dependsOn(j)
|
g.incl i.dependsOn(j)
|
||||||
|
|
||||||
proc markDirty*(g: ModuleGraph; fileIdx: FileIndex) =
|
proc markDirty*(g: ModuleGraph; fileIdx: FileIndex) =
|
||||||
let m = getModule fileIdx
|
let m = g.getModule fileIdx
|
||||||
if m != nil: incl m.flags, sfDirty
|
if m != nil: incl m.flags, sfDirty
|
||||||
|
|
||||||
proc markClientsDirty*(g: ModuleGraph; fileIdx: FileIndex) =
|
proc markClientsDirty*(g: ModuleGraph; fileIdx: FileIndex) =
|
||||||
# we need to mark its dependent modules D as dirty right away because after
|
# we need to mark its dependent modules D as dirty right away because after
|
||||||
# nimsuggest is done with this module, the module's dirty flag will be
|
# nimsuggest is done with this module, the module's dirty flag will be
|
||||||
# cleared but D still needs to be remembered as 'dirty'.
|
# cleared but D still needs to be remembered as 'dirty'.
|
||||||
if invalidTransitiveClosure:
|
if g.invalidTransitiveClosure:
|
||||||
invalidTransitiveClosure = false
|
g.invalidTransitiveClosure = false
|
||||||
transitiveClosure(deps, modules.len)
|
transitiveClosure(g.deps, g.modules.len)
|
||||||
|
|
||||||
# every module that *depends* on this file is also dirty:
|
# every module that *depends* on this file is also dirty:
|
||||||
for i in 0i32..<modules.len.int32:
|
for i in 0i32..<g.modules.len.int32:
|
||||||
let m = modules[i]
|
let m = g.modules[i]
|
||||||
if m != nil and deps.contains(i.dependsOn(fileIdx.int)):
|
if m != nil and g.deps.contains(i.dependsOn(fileIdx.int)):
|
||||||
incl m.flags, sfDirty
|
incl m.flags, sfDirty
|
||||||
|
|
||||||
proc isDirty*(g: ModuleGraph; m: PSym): bool =
|
proc isDirty*(g: ModuleGraph; m: PSym): bool =
|
||||||
result = suggestMode and sfDirty in m.flags
|
result = g.suggestMode and sfDirty in m.flags
|
||||||
|
|
|
||||||
|
|
@ -1066,8 +1066,10 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||||
of wThis:
|
of wThis:
|
||||||
if it.kind in nkPragmaCallKinds and it.len == 2:
|
if it.kind in nkPragmaCallKinds and it.len == 2:
|
||||||
c.selfName = considerQuotedIdent(c, it[1])
|
c.selfName = considerQuotedIdent(c, it[1])
|
||||||
|
message(c.config, n.info, warnDeprecated, "the '.this' pragma")
|
||||||
elif it.kind == nkIdent or it.len == 1:
|
elif it.kind == nkIdent or it.len == 1:
|
||||||
c.selfName = getIdent(c.cache, "self")
|
c.selfName = getIdent(c.cache, "self")
|
||||||
|
message(c.config, n.info, warnDeprecated, "the '.this' pragma")
|
||||||
else:
|
else:
|
||||||
localError(c.config, it.info, "'this' pragma is allowed to have zero or one arguments")
|
localError(c.config, it.info, "'this' pragma is allowed to have zero or one arguments")
|
||||||
of wNoRewrite:
|
of wNoRewrite:
|
||||||
|
|
|
||||||
|
|
@ -2336,6 +2336,8 @@ pointer type and overloading resolution is tried with ``a[]`` instead.
|
||||||
Automatic self insertions
|
Automatic self insertions
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
|
**Note**: The ``.this`` pragma is deprecated and should not be used anymore.
|
||||||
|
|
||||||
Starting with version 0.14 of the language, Nim supports ``field`` as a
|
Starting with version 0.14 of the language, Nim supports ``field`` as a
|
||||||
shortcut for ``self.field`` comparable to the `this`:idx: keyword in Java
|
shortcut for ``self.field`` comparable to the `this`:idx: keyword in Java
|
||||||
or C++. This feature has to be explicitly enabled via a ``{.this: self.}``
|
or C++. This feature has to be explicitly enabled via a ``{.this: self.}``
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue