big compiler refactoring; avoid globals for multi method dispatcher generation
This commit is contained in:
parent
311253ef2f
commit
46efaf294b
29 changed files with 225 additions and 215 deletions
|
|
@ -1366,7 +1366,7 @@ proc updateCachedModule(m: BModule) =
|
||||||
cf.flags = {CfileFlag.Cached}
|
cf.flags = {CfileFlag.Cached}
|
||||||
addFileToCompile(cf)
|
addFileToCompile(cf)
|
||||||
|
|
||||||
proc myClose(b: PPassContext, n: PNode): PNode =
|
proc myClose(graph: ModuleGraph; b: PPassContext, n: PNode): PNode =
|
||||||
result = n
|
result = n
|
||||||
if b == nil or passes.skipCodegen(n): return
|
if b == nil or passes.skipCodegen(n): return
|
||||||
var m = BModule(b)
|
var m = BModule(b)
|
||||||
|
|
@ -1378,7 +1378,7 @@ proc myClose(b: PPassContext, n: PNode): PNode =
|
||||||
|
|
||||||
if sfMainModule in m.module.flags:
|
if sfMainModule in m.module.flags:
|
||||||
incl m.flags, objHasKidsValid
|
incl m.flags, objHasKidsValid
|
||||||
var disp = generateMethodDispatchers()
|
var disp = generateMethodDispatchers(graph)
|
||||||
for i in 0..sonsLen(disp)-1: genProcAux(m, disp.sons[i].sym)
|
for i in 0..sonsLen(disp)-1: genProcAux(m, disp.sons[i].sym)
|
||||||
genMainProc(m)
|
genMainProc(m)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
intsets, options, ast, astalgo, msgs, idents, renderer, types, magicsys,
|
intsets, options, ast, astalgo, msgs, idents, renderer, types, magicsys,
|
||||||
sempass2, strutils
|
sempass2, strutils, modulegraphs
|
||||||
|
|
||||||
proc genConv(n: PNode, d: PType, downcast: bool): PNode =
|
proc genConv(n: PNode, d: PType, downcast: bool): PNode =
|
||||||
var dest = skipTypes(d, abstractPtrs)
|
var dest = skipTypes(d, abstractPtrs)
|
||||||
|
|
@ -38,16 +38,18 @@ proc genConv(n: PNode, d: PType, downcast: bool): PNode =
|
||||||
proc methodCall*(n: PNode): PNode =
|
proc methodCall*(n: PNode): PNode =
|
||||||
result = n
|
result = n
|
||||||
# replace ordinary method by dispatcher method:
|
# replace ordinary method by dispatcher method:
|
||||||
var disp = lastSon(result.sons[0].sym.ast).sym
|
let dispn = lastSon(result.sons[0].sym.ast)
|
||||||
assert sfDispatcher in disp.flags
|
if dispn.kind == nkSym:
|
||||||
|
let disp = dispn.sym
|
||||||
|
if sfDispatcher notin disp.flags:
|
||||||
|
localError(n.info, "'" & $result & "' lacks a dispatcher")
|
||||||
|
return
|
||||||
result.sons[0].sym = disp
|
result.sons[0].sym = disp
|
||||||
# change the arguments to up/downcasts to fit the dispatcher's parameters:
|
# change the arguments to up/downcasts to fit the dispatcher's parameters:
|
||||||
for i in countup(1, sonsLen(result)-1):
|
for i in countup(1, sonsLen(result)-1):
|
||||||
result.sons[i] = genConv(result.sons[i], disp.typ.sons[i], true)
|
result.sons[i] = genConv(result.sons[i], disp.typ.sons[i], true)
|
||||||
|
else:
|
||||||
# save for incremental compilation:
|
localError(n.info, "'" & $result.sons[0] & "' lacks a dispatcher")
|
||||||
var
|
|
||||||
gMethods: seq[tuple[methods: TSymSeq, dispatcher: PSym]] = @[]
|
|
||||||
|
|
||||||
type
|
type
|
||||||
MethodResult = enum No, Invalid, Yes
|
MethodResult = enum No, Invalid, Yes
|
||||||
|
|
@ -144,27 +146,27 @@ proc fixupDispatcher(meth, disp: PSym) =
|
||||||
if disp.typ.lockLevel < meth.typ.lockLevel:
|
if disp.typ.lockLevel < meth.typ.lockLevel:
|
||||||
disp.typ.lockLevel = meth.typ.lockLevel
|
disp.typ.lockLevel = meth.typ.lockLevel
|
||||||
|
|
||||||
proc methodDef*(s: PSym, fromCache: bool) =
|
proc methodDef*(g: ModuleGraph; s: PSym, fromCache: bool) =
|
||||||
let L = len(gMethods)
|
let L = len(g.methods)
|
||||||
var witness: PSym
|
var witness: PSym
|
||||||
for i in countup(0, L - 1):
|
for i in countup(0, L - 1):
|
||||||
let disp = gMethods[i].dispatcher
|
let disp = g.methods[i].dispatcher
|
||||||
case sameMethodBucket(disp, s)
|
case sameMethodBucket(disp, s)
|
||||||
of Yes:
|
of Yes:
|
||||||
add(gMethods[i].methods, s)
|
add(g.methods[i].methods, s)
|
||||||
attachDispatcher(s, lastSon(disp.ast))
|
attachDispatcher(s, lastSon(disp.ast))
|
||||||
fixupDispatcher(s, disp)
|
fixupDispatcher(s, disp)
|
||||||
#echo "fixup ", disp.name.s, " ", disp.id
|
#echo "fixup ", disp.name.s, " ", disp.id
|
||||||
when useEffectSystem: checkMethodEffects(disp, s)
|
when useEffectSystem: checkMethodEffects(disp, s)
|
||||||
if sfBase in s.flags and gMethods[i].methods[0] != s:
|
if sfBase in s.flags and g.methods[i].methods[0] != s:
|
||||||
# already exists due to forwarding definition?
|
# already exists due to forwarding definition?
|
||||||
localError(s.info, "method is not a base")
|
localError(s.info, "method is not a base")
|
||||||
return
|
return
|
||||||
of No: discard
|
of No: discard
|
||||||
of Invalid:
|
of Invalid:
|
||||||
if witness.isNil: witness = gMethods[i].methods[0]
|
if witness.isNil: witness = g.methods[i].methods[0]
|
||||||
# create a new dispatcher:
|
# create a new dispatcher:
|
||||||
add(gMethods, (methods: @[s], dispatcher: createDispatcher(s)))
|
add(g.methods, (methods: @[s], dispatcher: createDispatcher(s)))
|
||||||
#echo "adding ", s.info
|
#echo "adding ", s.info
|
||||||
#if fromCache:
|
#if fromCache:
|
||||||
# internalError(s.info, "no method dispatcher found")
|
# internalError(s.info, "no method dispatcher found")
|
||||||
|
|
@ -258,12 +260,12 @@ proc genDispatcher(methods: TSymSeq, relevantCols: IntSet): PSym =
|
||||||
disp = ret
|
disp = ret
|
||||||
result.ast.sons[bodyPos] = disp
|
result.ast.sons[bodyPos] = disp
|
||||||
|
|
||||||
proc generateMethodDispatchers*(): PNode =
|
proc generateMethodDispatchers*(g: ModuleGraph): PNode =
|
||||||
result = newNode(nkStmtList)
|
result = newNode(nkStmtList)
|
||||||
for bucket in countup(0, len(gMethods) - 1):
|
for bucket in countup(0, len(g.methods) - 1):
|
||||||
var relevantCols = initIntSet()
|
var relevantCols = initIntSet()
|
||||||
for col in countup(1, sonsLen(gMethods[bucket].methods[0].typ) - 1):
|
for col in countup(1, sonsLen(g.methods[bucket].methods[0].typ) - 1):
|
||||||
if relevantCol(gMethods[bucket].methods, col): incl(relevantCols, col)
|
if relevantCol(g.methods[bucket].methods, col): incl(relevantCols, col)
|
||||||
sortBucket(gMethods[bucket].methods, relevantCols)
|
sortBucket(g.methods[bucket].methods, relevantCols)
|
||||||
addSon(result,
|
addSon(result,
|
||||||
newSymNode(genDispatcher(gMethods[bucket].methods, relevantCols)))
|
newSymNode(genDispatcher(g.methods[bucket].methods, relevantCols)))
|
||||||
|
|
|
||||||
|
|
@ -33,11 +33,11 @@ template closeImpl(body: untyped) {.dirty.} =
|
||||||
except IOError:
|
except IOError:
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc close(p: PPassContext, n: PNode): PNode =
|
proc close(graph: ModuleGraph; p: PPassContext, n: PNode): PNode =
|
||||||
closeImpl:
|
closeImpl:
|
||||||
writeOutput(g.doc, g.module.filename, HtmlExt, useWarning)
|
writeOutput(g.doc, g.module.filename, HtmlExt, useWarning)
|
||||||
|
|
||||||
proc closeJson(p: PPassContext, n: PNode): PNode =
|
proc closeJson(graph: ModuleGraph; p: PPassContext, n: PNode): PNode =
|
||||||
closeImpl:
|
closeImpl:
|
||||||
writeOutputJson(g.doc, g.module.filename, ".json", useWarning)
|
writeOutputJson(g.doc, g.module.filename, ".json", useWarning)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2237,13 +2237,13 @@ proc myProcess(b: PPassContext, n: PNode): PNode =
|
||||||
add(p.g.code, p.body)
|
add(p.g.code, p.body)
|
||||||
globals.unique = p.unique
|
globals.unique = p.unique
|
||||||
|
|
||||||
proc wholeCode*(m: BModule): Rope =
|
proc wholeCode(graph: ModuleGraph; m: BModule): Rope =
|
||||||
for prc in globals.forwarded:
|
for prc in globals.forwarded:
|
||||||
if not globals.generatedSyms.containsOrIncl(prc.id):
|
if not globals.generatedSyms.containsOrIncl(prc.id):
|
||||||
var p = newProc(globals, m, nil, m.module.options)
|
var p = newProc(globals, m, nil, m.module.options)
|
||||||
attachProc(p, prc)
|
attachProc(p, prc)
|
||||||
|
|
||||||
var disp = generateMethodDispatchers()
|
var disp = generateMethodDispatchers(graph)
|
||||||
for i in 0..sonsLen(disp)-1:
|
for i in 0..sonsLen(disp)-1:
|
||||||
let prc = disp.sons[i].sym
|
let prc = disp.sons[i].sym
|
||||||
if not globals.generatedSyms.containsOrIncl(prc.id):
|
if not globals.generatedSyms.containsOrIncl(prc.id):
|
||||||
|
|
@ -2277,7 +2277,7 @@ proc genClass(obj: PType; content: Rope; ext: string) =
|
||||||
let outfile = changeFileExt(completeCFilePath($cls), ext)
|
let outfile = changeFileExt(completeCFilePath($cls), ext)
|
||||||
discard writeRopeIfNotEqual(result, outfile)
|
discard writeRopeIfNotEqual(result, outfile)
|
||||||
|
|
||||||
proc myClose(b: PPassContext, n: PNode): PNode =
|
proc myClose(graph: ModuleGraph; b: PPassContext, n: PNode): PNode =
|
||||||
if passes.skipCodegen(n): return n
|
if passes.skipCodegen(n): return n
|
||||||
result = myProcess(b, n)
|
result = myProcess(b, n)
|
||||||
var m = BModule(b)
|
var m = BModule(b)
|
||||||
|
|
@ -2285,7 +2285,7 @@ proc myClose(b: PPassContext, n: PNode): PNode =
|
||||||
let ext = if m.target == targetJS: "js" else: "php"
|
let ext = if m.target == targetJS: "js" else: "php"
|
||||||
let f = if globals.classes.len == 0: m.module.filename
|
let f = if globals.classes.len == 0: m.module.filename
|
||||||
else: "nimsystem"
|
else: "nimsystem"
|
||||||
let code = wholeCode(m)
|
let code = wholeCode(graph, m)
|
||||||
let outfile =
|
let outfile =
|
||||||
if options.outFile.len > 0:
|
if options.outFile.len > 0:
|
||||||
if options.outFile.isAbsolute: options.outFile
|
if options.outFile.isAbsolute: options.outFile
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ proc errorSym*(c: PContext, n: PNode): PSym =
|
||||||
considerQuotedIdent(m)
|
considerQuotedIdent(m)
|
||||||
else:
|
else:
|
||||||
getIdent("err:" & renderTree(m))
|
getIdent("err:" & renderTree(m))
|
||||||
result = newSym(skError, ident, getCurrOwner(), n.info)
|
result = newSym(skError, ident, getCurrOwner(c), n.info)
|
||||||
result.typ = errorType(c)
|
result.typ = errorType(c)
|
||||||
incl(result.flags, sfDiscardable)
|
incl(result.flags, sfDiscardable)
|
||||||
# pretend it's imported from some unknown module to prevent cascading errors:
|
# pretend it's imported from some unknown module to prevent cascading errors:
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,9 @@ type
|
||||||
backend*: RootRef # minor hack so that a backend can extend this easily
|
backend*: RootRef # minor hack so that a backend can extend this easily
|
||||||
config*: ConfigRef
|
config*: ConfigRef
|
||||||
doStopCompile*: proc(): bool {.closure.}
|
doStopCompile*: proc(): bool {.closure.}
|
||||||
|
usageSym*: PSym # for nimsuggest
|
||||||
|
owners*: seq[PSym]
|
||||||
|
methods*: seq[tuple[methods: TSymSeq, dispatcher: PSym]]
|
||||||
|
|
||||||
{.this: g.}
|
{.this: g.}
|
||||||
|
|
||||||
|
|
@ -58,6 +61,8 @@ proc newModuleGraph*(config: ConfigRef = nil): ModuleGraph =
|
||||||
result.config = newConfigRef()
|
result.config = newConfigRef()
|
||||||
else:
|
else:
|
||||||
result.config = config
|
result.config = config
|
||||||
|
result.owners = @[]
|
||||||
|
result.methods = @[]
|
||||||
|
|
||||||
proc resetAllModules*(g: ModuleGraph) =
|
proc resetAllModules*(g: ModuleGraph) =
|
||||||
initStrTable(packageSyms)
|
initStrTable(packageSyms)
|
||||||
|
|
@ -65,6 +70,9 @@ proc resetAllModules*(g: ModuleGraph) =
|
||||||
modules = @[]
|
modules = @[]
|
||||||
importStack = @[]
|
importStack = @[]
|
||||||
inclToMod = initTable[int32, int32]()
|
inclToMod = initTable[int32, int32]()
|
||||||
|
usageSym = nil
|
||||||
|
owners = @[]
|
||||||
|
methods = @[]
|
||||||
|
|
||||||
proc getModule*(g: ModuleGraph; fileIdx: int32): PSym =
|
proc getModule*(g: ModuleGraph; fileIdx: int32): PSym =
|
||||||
if fileIdx >= 0 and fileIdx < modules.len:
|
if fileIdx >= 0 and fileIdx < modules.len:
|
||||||
|
|
|
||||||
|
|
@ -567,6 +567,15 @@ proc newFileInfo(fullPath, projPath: string): TFileInfo =
|
||||||
if optEmbedOrigSrc in gGlobalOptions or true:
|
if optEmbedOrigSrc in gGlobalOptions or true:
|
||||||
result.lines = @[]
|
result.lines = @[]
|
||||||
|
|
||||||
|
proc fileInfoKnown*(filename: string): bool =
|
||||||
|
var
|
||||||
|
canon: string
|
||||||
|
try:
|
||||||
|
canon = canonicalizePath(filename)
|
||||||
|
except:
|
||||||
|
canon = filename
|
||||||
|
result = filenameToIndexTbl.hasKey(canon)
|
||||||
|
|
||||||
proc fileInfoIdx*(filename: string; isKnownFile: var bool): int32 =
|
proc fileInfoIdx*(filename: string; isKnownFile: var bool): int32 =
|
||||||
var
|
var
|
||||||
canon: string
|
canon: string
|
||||||
|
|
|
||||||
|
|
@ -29,21 +29,3 @@ proc verboseProcess(context: PPassContext, n: PNode): PNode =
|
||||||
message(n.info, hintProcessing, $idgen.gFrontendId)
|
message(n.info, hintProcessing, $idgen.gFrontendId)
|
||||||
|
|
||||||
const verbosePass* = makePass(open = verboseOpen, process = verboseProcess)
|
const verbosePass* = makePass(open = verboseOpen, process = verboseProcess)
|
||||||
|
|
||||||
proc cleanUp(c: PPassContext, n: PNode): PNode =
|
|
||||||
result = n
|
|
||||||
# we cannot clean up if dead code elimination is activated
|
|
||||||
if optDeadCodeElim in gGlobalOptions or n == nil: return
|
|
||||||
case n.kind
|
|
||||||
of nkStmtList:
|
|
||||||
for i in countup(0, sonsLen(n) - 1): discard cleanUp(c, n.sons[i])
|
|
||||||
of nkProcDef, nkMethodDef:
|
|
||||||
if n.sons[namePos].kind == nkSym:
|
|
||||||
var s = n.sons[namePos].sym
|
|
||||||
if sfDeadCodeElim notin getModule(s).flags and not astNeeded(s):
|
|
||||||
s.ast.sons[bodyPos] = ast.emptyNode # free the memory
|
|
||||||
else:
|
|
||||||
discard
|
|
||||||
|
|
||||||
const cleanupPass* = makePass(process = cleanUp, close = cleanUp)
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ type
|
||||||
TPassOpen* = proc (graph: ModuleGraph; module: PSym; cache: IdentCache): PPassContext {.nimcall.}
|
TPassOpen* = proc (graph: ModuleGraph; module: PSym; cache: IdentCache): PPassContext {.nimcall.}
|
||||||
TPassOpenCached* =
|
TPassOpenCached* =
|
||||||
proc (graph: ModuleGraph; module: PSym, rd: PRodReader): PPassContext {.nimcall.}
|
proc (graph: ModuleGraph; module: PSym, rd: PRodReader): PPassContext {.nimcall.}
|
||||||
TPassClose* = proc (p: PPassContext, n: PNode): PNode {.nimcall.}
|
TPassClose* = proc (graph: ModuleGraph; p: PPassContext, n: PNode): PNode {.nimcall.}
|
||||||
TPassProcess* = proc (p: PPassContext, topLevelStmt: PNode): PNode {.nimcall.}
|
TPassProcess* = proc (p: PPassContext, topLevelStmt: PNode): PNode {.nimcall.}
|
||||||
|
|
||||||
TPass* = tuple[open: TPassOpen, openCached: TPassOpenCached,
|
TPass* = tuple[open: TPassOpen, openCached: TPassOpenCached,
|
||||||
|
|
@ -94,7 +94,7 @@ proc carryPass*(g: ModuleGraph; p: TPass, module: PSym; cache: IdentCache;
|
||||||
m: TPassData): TPassData =
|
m: TPassData): TPassData =
|
||||||
var c = p.open(g, module, cache)
|
var c = p.open(g, module, cache)
|
||||||
result.input = p.process(c, m.input)
|
result.input = p.process(c, m.input)
|
||||||
result.closeOutput = if p.close != nil: p.close(c, m.closeOutput)
|
result.closeOutput = if p.close != nil: p.close(g, c, m.closeOutput)
|
||||||
else: m.closeOutput
|
else: m.closeOutput
|
||||||
|
|
||||||
proc carryPasses*(g: ModuleGraph; nodes: PNode, module: PSym;
|
proc carryPasses*(g: ModuleGraph; nodes: PNode, module: PSym;
|
||||||
|
|
@ -121,10 +121,10 @@ proc openPassesCached(g: ModuleGraph; a: var TPassContextArray, module: PSym,
|
||||||
else:
|
else:
|
||||||
a[i] = nil
|
a[i] = nil
|
||||||
|
|
||||||
proc closePasses(a: var TPassContextArray) =
|
proc closePasses(graph: ModuleGraph; a: var TPassContextArray) =
|
||||||
var m: PNode = nil
|
var m: PNode = nil
|
||||||
for i in countup(0, gPassesLen - 1):
|
for i in countup(0, gPassesLen - 1):
|
||||||
if not isNil(gPasses[i].close): m = gPasses[i].close(a[i], m)
|
if not isNil(gPasses[i].close): m = gPasses[i].close(graph, a[i], m)
|
||||||
a[i] = nil # free the memory here
|
a[i] = nil # free the memory here
|
||||||
|
|
||||||
proc processTopLevelStmt(n: PNode, a: var TPassContextArray): bool =
|
proc processTopLevelStmt(n: PNode, a: var TPassContextArray): bool =
|
||||||
|
|
@ -142,11 +142,11 @@ proc processTopLevelStmtCached(n: PNode, a: var TPassContextArray) =
|
||||||
for i in countup(0, gPassesLen - 1):
|
for i in countup(0, gPassesLen - 1):
|
||||||
if not isNil(gPasses[i].openCached): m = gPasses[i].process(a[i], m)
|
if not isNil(gPasses[i].openCached): m = gPasses[i].process(a[i], m)
|
||||||
|
|
||||||
proc closePassesCached(a: var TPassContextArray) =
|
proc closePassesCached(graph: ModuleGraph; a: var TPassContextArray) =
|
||||||
var m: PNode = nil
|
var m: PNode = nil
|
||||||
for i in countup(0, gPassesLen - 1):
|
for i in countup(0, gPassesLen - 1):
|
||||||
if not isNil(gPasses[i].openCached) and not isNil(gPasses[i].close):
|
if not isNil(gPasses[i].openCached) and not isNil(gPasses[i].close):
|
||||||
m = gPasses[i].close(a[i], m)
|
m = gPasses[i].close(graph, a[i], m)
|
||||||
a[i] = nil # free the memory here
|
a[i] = nil # free the memory here
|
||||||
|
|
||||||
proc resolveMod(module, relativeTo: string): int32 =
|
proc resolveMod(module, relativeTo: string): int32 =
|
||||||
|
|
@ -215,7 +215,7 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream,
|
||||||
elif not processTopLevelStmt(n, a): break
|
elif not processTopLevelStmt(n, a): break
|
||||||
closeParsers(p)
|
closeParsers(p)
|
||||||
if s.kind != llsStdIn: break
|
if s.kind != llsStdIn: break
|
||||||
closePasses(a)
|
closePasses(graph, a)
|
||||||
# id synchronization point for more consistent code generation:
|
# id synchronization point for more consistent code generation:
|
||||||
idSynchronizationPoint(1000)
|
idSynchronizationPoint(1000)
|
||||||
else:
|
else:
|
||||||
|
|
@ -224,5 +224,5 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream,
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
if graph.stopCompile(): break
|
if graph.stopCompile(): break
|
||||||
processTopLevelStmtCached(n.sons[i], a)
|
processTopLevelStmtCached(n.sons[i], a)
|
||||||
closePassesCached(a)
|
closePassesCached(graph, a)
|
||||||
result = true
|
result = true
|
||||||
|
|
|
||||||
|
|
@ -289,7 +289,7 @@ proc applyRule*(c: PContext, s: PSym, n: PNode): PNode =
|
||||||
# constraint not fulfilled:
|
# constraint not fulfilled:
|
||||||
if not ok: return nil
|
if not ok: return nil
|
||||||
|
|
||||||
markUsed(n.info, s)
|
markUsed(n.info, s, c.graph.usageSym)
|
||||||
if ctx.subMatch:
|
if ctx.subMatch:
|
||||||
assert m.len == 3
|
assert m.len == 3
|
||||||
m.sons[1] = result
|
m.sons[1] = result
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ proc semLocals(c: PContext, n: PNode): PNode =
|
||||||
it.typ.skipTypes({tyGenericInst, tyVar}).kind notin
|
it.typ.skipTypes({tyGenericInst, tyVar}).kind notin
|
||||||
{tyVarargs, tyOpenArray, tyTypeDesc, tyStatic, tyExpr, tyStmt, tyEmpty}:
|
{tyVarargs, tyOpenArray, tyTypeDesc, tyStatic, tyExpr, tyStmt, tyEmpty}:
|
||||||
|
|
||||||
var field = newSym(skField, it.name, getCurrOwner(), n.info)
|
var field = newSym(skField, it.name, getCurrOwner(c), n.info)
|
||||||
field.typ = it.typ.skipTypes({tyGenericInst, tyVar})
|
field.typ = it.typ.skipTypes({tyGenericInst, tyVar})
|
||||||
field.position = counter
|
field.position = counter
|
||||||
inc(counter)
|
inc(counter)
|
||||||
|
|
|
||||||
|
|
@ -641,7 +641,7 @@ proc myOpen(g: ModuleGraph; module: PSym; cache: IdentCache): PPassContext =
|
||||||
rawAddInterfaceSym(w, module)
|
rawAddInterfaceSym(w, module)
|
||||||
result = w
|
result = w
|
||||||
|
|
||||||
proc myClose(c: PPassContext, n: PNode): PNode =
|
proc myClose(graph: ModuleGraph; c: PPassContext, n: PNode): PNode =
|
||||||
result = process(c, n)
|
result = process(c, n)
|
||||||
var w = PRodWriter(c)
|
var w = PRodWriter(c)
|
||||||
writeRod(w)
|
writeRod(w)
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,7 @@ proc commonType*(x, y: PType): PType =
|
||||||
result.addSonSkipIntLit(r)
|
result.addSonSkipIntLit(r)
|
||||||
|
|
||||||
proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym =
|
proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym =
|
||||||
result = newSym(kind, considerQuotedIdent(n), getCurrOwner(), n.info)
|
result = newSym(kind, considerQuotedIdent(n), getCurrOwner(c), n.info)
|
||||||
|
|
||||||
proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym =
|
proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym =
|
||||||
proc `$`(kind: TSymKind): string = substr(system.`$`(kind), 2).toLowerAscii
|
proc `$`(kind: TSymKind): string = substr(system.`$`(kind), 2).toLowerAscii
|
||||||
|
|
@ -186,9 +186,9 @@ proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym =
|
||||||
# when there is a nested proc inside a template, semtmpl
|
# when there is a nested proc inside a template, semtmpl
|
||||||
# will assign a wrong owner during the first pass over the
|
# will assign a wrong owner during the first pass over the
|
||||||
# template; we must fix it here: see #909
|
# template; we must fix it here: see #909
|
||||||
result.owner = getCurrOwner()
|
result.owner = getCurrOwner(c)
|
||||||
else:
|
else:
|
||||||
result = newSym(kind, considerQuotedIdent(n), getCurrOwner(), n.info)
|
result = newSym(kind, considerQuotedIdent(n), getCurrOwner(c), n.info)
|
||||||
#if kind in {skForVar, skLet, skVar} and result.owner.kind == skModule:
|
#if kind in {skForVar, skLet, skVar} and result.owner.kind == skModule:
|
||||||
# incl(result.flags, sfGlobal)
|
# incl(result.flags, sfGlobal)
|
||||||
|
|
||||||
|
|
@ -376,7 +376,7 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
|
||||||
flags: TExprFlags = {}): PNode =
|
flags: TExprFlags = {}): PNode =
|
||||||
pushInfoContext(nOrig.info)
|
pushInfoContext(nOrig.info)
|
||||||
|
|
||||||
markUsed(n.info, sym)
|
markUsed(n.info, sym, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, sym)
|
styleCheckUse(n.info, sym)
|
||||||
if sym == c.p.owner:
|
if sym == c.p.owner:
|
||||||
globalError(n.info, errRecursiveDependencyX, sym.name.s)
|
globalError(n.info, errRecursiveDependencyX, sym.name.s)
|
||||||
|
|
@ -434,7 +434,7 @@ proc myOpen(graph: ModuleGraph; module: PSym; cache: IdentCache): PPassContext =
|
||||||
c.instTypeBoundOp = sigmatch.instTypeBoundOp
|
c.instTypeBoundOp = sigmatch.instTypeBoundOp
|
||||||
|
|
||||||
pushProcCon(c, module)
|
pushProcCon(c, module)
|
||||||
pushOwner(c.module)
|
pushOwner(c, c.module)
|
||||||
c.importTable = openScope(c)
|
c.importTable = openScope(c)
|
||||||
c.importTable.addSym(module) # a module knows itself
|
c.importTable.addSym(module) # a module knows itself
|
||||||
if sfSystemModule in module.flags:
|
if sfSystemModule in module.flags:
|
||||||
|
|
@ -450,7 +450,7 @@ proc myOpen(graph: ModuleGraph; module: PSym; cache: IdentCache): PPassContext =
|
||||||
|
|
||||||
proc myOpenCached(graph: ModuleGraph; module: PSym; rd: PRodReader): PPassContext =
|
proc myOpenCached(graph: ModuleGraph; module: PSym; rd: PRodReader): PPassContext =
|
||||||
result = myOpen(graph, module, rd.cache)
|
result = myOpen(graph, module, rd.cache)
|
||||||
for m in items(rd.methods): methodDef(m, true)
|
for m in items(rd.methods): methodDef(graph, m, true)
|
||||||
|
|
||||||
proc isImportSystemStmt(n: PNode): bool =
|
proc isImportSystemStmt(n: PNode): bool =
|
||||||
if magicsys.systemModule == nil: return false
|
if magicsys.systemModule == nil: return false
|
||||||
|
|
@ -502,7 +502,7 @@ proc recoverContext(c: PContext) =
|
||||||
# faster than wrapping every stack operation in a 'try finally' block and
|
# faster than wrapping every stack operation in a 'try finally' block and
|
||||||
# requires far less code.
|
# requires far less code.
|
||||||
c.currentScope = c.topLevelScope
|
c.currentScope = c.topLevelScope
|
||||||
while getCurrOwner().kind != skModule: popOwner()
|
while getCurrOwner(c).kind != skModule: popOwner(c)
|
||||||
while c.p != nil and c.p.owner.kind != skModule: c.p = c.p.next
|
while c.p != nil and c.p.owner.kind != skModule: c.p = c.p.next
|
||||||
|
|
||||||
proc myProcess(context: PPassContext, n: PNode): PNode =
|
proc myProcess(context: PPassContext, n: PNode): PNode =
|
||||||
|
|
@ -523,7 +523,7 @@ proc myProcess(context: PPassContext, n: PNode): PNode =
|
||||||
else: result = ast.emptyNode
|
else: result = ast.emptyNode
|
||||||
#if gCmd == cmdIdeTools: findSuggest(c, n)
|
#if gCmd == cmdIdeTools: findSuggest(c, n)
|
||||||
|
|
||||||
proc myClose(context: PPassContext, n: PNode): PNode =
|
proc myClose(graph: ModuleGraph; context: PPassContext, n: PNode): PNode =
|
||||||
var c = PContext(context)
|
var c = PContext(context)
|
||||||
closeScope(c) # close module's scope
|
closeScope(c) # close module's scope
|
||||||
rawCloseScope(c) # imported symbols; don't check for unused ones!
|
rawCloseScope(c) # imported symbols; don't check for unused ones!
|
||||||
|
|
@ -533,7 +533,7 @@ proc myClose(context: PPassContext, n: PNode): PNode =
|
||||||
addCodeForGenerics(c, result)
|
addCodeForGenerics(c, result)
|
||||||
if c.module.ast != nil:
|
if c.module.ast != nil:
|
||||||
result.add(c.module.ast)
|
result.add(c.module.ast)
|
||||||
popOwner()
|
popOwner(c)
|
||||||
popProcCon(c)
|
popProcCon(c)
|
||||||
|
|
||||||
const semPass* = makePass(myOpen, myOpenCached, myProcess, myClose)
|
const semPass* = makePass(myOpen, myOpenCached, myProcess, myClose)
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ proc considerOverloadedOp(c: var TLiftCtx; t: PType; body, x, y: PNode): bool =
|
||||||
of attachedDestructor:
|
of attachedDestructor:
|
||||||
let op = t.destructor
|
let op = t.destructor
|
||||||
if op != nil:
|
if op != nil:
|
||||||
markUsed(c.info, op)
|
markUsed(c.info, op, c.c.graph.usageSym)
|
||||||
styleCheckUse(c.info, op)
|
styleCheckUse(c.info, op)
|
||||||
body.add newDestructorCall(op, x)
|
body.add newDestructorCall(op, x)
|
||||||
result = true
|
result = true
|
||||||
|
|
@ -123,14 +123,14 @@ proc considerOverloadedOp(c: var TLiftCtx; t: PType; body, x, y: PNode): bool =
|
||||||
op = t.assignment
|
op = t.assignment
|
||||||
if op == nil:
|
if op == nil:
|
||||||
op = liftBody(c.c, t, c.info)
|
op = liftBody(c.c, t, c.info)
|
||||||
markUsed(c.info, op)
|
markUsed(c.info, op, c.c.graph.usageSym)
|
||||||
styleCheckUse(c.info, op)
|
styleCheckUse(c.info, op)
|
||||||
body.add newAsgnCall(c.c, op, x, y)
|
body.add newAsgnCall(c.c, op, x, y)
|
||||||
result = true
|
result = true
|
||||||
of attachedDeepCopy:
|
of attachedDeepCopy:
|
||||||
let op = t.deepCopy
|
let op = t.deepCopy
|
||||||
if op != nil:
|
if op != nil:
|
||||||
markUsed(c.info, op)
|
markUsed(c.info, op, c.c.graph.usageSym)
|
||||||
styleCheckUse(c.info, op)
|
styleCheckUse(c.info, op)
|
||||||
body.add newDeepCopyCall(op, x, y)
|
body.add newDeepCopyCall(op, x, y)
|
||||||
result = true
|
result = true
|
||||||
|
|
|
||||||
|
|
@ -335,7 +335,7 @@ proc inferWithMetatype(c: PContext, formal: PType,
|
||||||
proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode =
|
proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode =
|
||||||
assert x.state == csMatch
|
assert x.state == csMatch
|
||||||
var finalCallee = x.calleeSym
|
var finalCallee = x.calleeSym
|
||||||
markUsed(n.sons[0].info, finalCallee)
|
markUsed(n.sons[0].info, finalCallee, c.graph.usageSym)
|
||||||
styleCheckUse(n.sons[0].info, finalCallee)
|
styleCheckUse(n.sons[0].info, finalCallee)
|
||||||
assert finalCallee.ast != nil
|
assert finalCallee.ast != nil
|
||||||
if x.hasFauxMatch:
|
if x.hasFauxMatch:
|
||||||
|
|
@ -411,7 +411,7 @@ proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode =
|
||||||
let tm = typeRel(m, formal, arg, true)
|
let tm = typeRel(m, formal, arg, true)
|
||||||
if tm in {isNone, isConvertible}: return nil
|
if tm in {isNone, isConvertible}: return nil
|
||||||
var newInst = generateInstance(c, s, m.bindings, n.info)
|
var newInst = generateInstance(c, s, m.bindings, n.info)
|
||||||
markUsed(n.info, s)
|
markUsed(n.info, s, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
result = newSymNode(newInst, n.info)
|
result = newSymNode(newInst, n.info)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -125,22 +125,20 @@ proc scopeDepth*(c: PContext): int {.inline.} =
|
||||||
result = if c.currentScope != nil: c.currentScope.depthLevel
|
result = if c.currentScope != nil: c.currentScope.depthLevel
|
||||||
else: 0
|
else: 0
|
||||||
|
|
||||||
var gOwners*: seq[PSym] = @[]
|
proc getCurrOwner*(c: PContext): PSym =
|
||||||
|
|
||||||
proc getCurrOwner*(): PSym =
|
|
||||||
# owner stack (used for initializing the
|
# owner stack (used for initializing the
|
||||||
# owner field of syms)
|
# owner field of syms)
|
||||||
# the documentation comment always gets
|
# the documentation comment always gets
|
||||||
# assigned to the current owner
|
# assigned to the current owner
|
||||||
# BUGFIX: global array is needed!
|
# BUGFIX: global array is needed!
|
||||||
result = gOwners[high(gOwners)]
|
result = c.graph.owners[^1]
|
||||||
|
|
||||||
proc pushOwner*(owner: PSym) =
|
proc pushOwner*(c: PContext; owner: PSym) =
|
||||||
add(gOwners, owner)
|
add(c.graph.owners, owner)
|
||||||
|
|
||||||
proc popOwner*() =
|
proc popOwner*(c: PContext) =
|
||||||
var length = len(gOwners)
|
var length = len(c.graph.owners)
|
||||||
if length > 0: setLen(gOwners, length - 1)
|
if length > 0: setLen(c.graph.owners, length - 1)
|
||||||
else: internalError("popOwner")
|
else: internalError("popOwner")
|
||||||
|
|
||||||
proc lastOptionEntry*(c: PContext): POptionEntry =
|
proc lastOptionEntry*(c: PContext): POptionEntry =
|
||||||
|
|
@ -226,7 +224,7 @@ proc addToLib*(lib: PLib, sym: PSym) =
|
||||||
sym.annex = lib
|
sym.annex = lib
|
||||||
|
|
||||||
proc newTypeS*(kind: TTypeKind, c: PContext): PType =
|
proc newTypeS*(kind: TTypeKind, c: PContext): PType =
|
||||||
result = newType(kind, getCurrOwner())
|
result = newType(kind, getCurrOwner(c))
|
||||||
|
|
||||||
proc makePtrType*(c: PContext, baseType: PType): PType =
|
proc makePtrType*(c: PContext, baseType: PType): PType =
|
||||||
result = newTypeS(tyPtr, c)
|
result = newTypeS(tyPtr, c)
|
||||||
|
|
@ -245,7 +243,7 @@ proc makeTypeDesc*(c: PContext, typ: PType): PType =
|
||||||
|
|
||||||
proc makeTypeSymNode*(c: PContext, typ: PType, info: TLineInfo): PNode =
|
proc makeTypeSymNode*(c: PContext, typ: PType, info: TLineInfo): PNode =
|
||||||
let typedesc = makeTypeDesc(c, typ)
|
let typedesc = makeTypeDesc(c, typ)
|
||||||
let sym = newSym(skType, c.cache.idAnon, getCurrOwner(), info).linkTo(typedesc)
|
let sym = newSym(skType, c.cache.idAnon, getCurrOwner(c), info).linkTo(typedesc)
|
||||||
return newSymNode(sym, info)
|
return newSymNode(sym, info)
|
||||||
|
|
||||||
proc makeTypeFromExpr*(c: PContext, n: PNode): PType =
|
proc makeTypeFromExpr*(c: PContext, n: PNode): PType =
|
||||||
|
|
@ -255,7 +253,7 @@ proc makeTypeFromExpr*(c: PContext, n: PNode): PType =
|
||||||
|
|
||||||
proc newTypeWithSons*(c: PContext, kind: TTypeKind,
|
proc newTypeWithSons*(c: PContext, kind: TTypeKind,
|
||||||
sons: seq[PType]): PType =
|
sons: seq[PType]): PType =
|
||||||
result = newType(kind, getCurrOwner())
|
result = newType(kind, getCurrOwner(c))
|
||||||
result.sons = sons
|
result.sons = sons
|
||||||
|
|
||||||
proc makeStaticExpr*(c: PContext, n: PNode): PNode =
|
proc makeStaticExpr*(c: PContext, n: PNode): PNode =
|
||||||
|
|
@ -326,7 +324,7 @@ proc errorNode*(c: PContext, n: PNode): PNode =
|
||||||
|
|
||||||
proc fillTypeS*(dest: PType, kind: TTypeKind, c: PContext) =
|
proc fillTypeS*(dest: PType, kind: TTypeKind, c: PContext) =
|
||||||
dest.kind = kind
|
dest.kind = kind
|
||||||
dest.owner = getCurrOwner()
|
dest.owner = getCurrOwner(c)
|
||||||
dest.size = - 1
|
dest.size = - 1
|
||||||
|
|
||||||
proc makeRangeType*(c: PContext; first, last: BiggestInt;
|
proc makeRangeType*(c: PContext; first, last: BiggestInt;
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ proc doDestructorStuff(c: PContext, s: PSym, n: PNode) =
|
||||||
let destructableT = instantiateDestructor(c, t.sons[i])
|
let destructableT = instantiateDestructor(c, t.sons[i])
|
||||||
if destructableT != nil:
|
if destructableT != nil:
|
||||||
n.sons[bodyPos].addSon(newNode(nkCall, t.sym.info, @[
|
n.sons[bodyPos].addSon(newNode(nkCall, t.sym.info, @[
|
||||||
useSym(destructableT.destructor),
|
useSym(destructableT.destructor, c.graph.usageSym),
|
||||||
n.sons[paramsPos][1][0]]))
|
n.sons[paramsPos][1][0]]))
|
||||||
|
|
||||||
proc destroyFieldOrFields(c: PContext, field: PNode, holder: PNode): PNode
|
proc destroyFieldOrFields(c: PContext, field: PNode, holder: PNode): PNode
|
||||||
|
|
@ -60,8 +60,8 @@ proc destroySym(c: PContext, field: PSym, holder: PNode): PNode =
|
||||||
let destructableT = instantiateDestructor(c, field.typ)
|
let destructableT = instantiateDestructor(c, field.typ)
|
||||||
if destructableT != nil:
|
if destructableT != nil:
|
||||||
result = newNode(nkCall, field.info, @[
|
result = newNode(nkCall, field.info, @[
|
||||||
useSym(destructableT.destructor),
|
useSym(destructableT.destructor, c.graph.usageSym),
|
||||||
newNode(nkDotExpr, field.info, @[holder, useSym(field)])])
|
newNode(nkDotExpr, field.info, @[holder, useSym(field, c.graph.usageSym)])])
|
||||||
|
|
||||||
proc destroyCase(c: PContext, n: PNode, holder: PNode): PNode =
|
proc destroyCase(c: PContext, n: PNode, holder: PNode): PNode =
|
||||||
var nonTrivialFields = 0
|
var nonTrivialFields = 0
|
||||||
|
|
@ -181,7 +181,8 @@ proc createDestructorCall(c: PContext, s: PSym): PNode =
|
||||||
let destructableT = instantiateDestructor(c, varTyp)
|
let destructableT = instantiateDestructor(c, varTyp)
|
||||||
if destructableT != nil:
|
if destructableT != nil:
|
||||||
let call = semStmt(c, newNode(nkCall, s.info, @[
|
let call = semStmt(c, newNode(nkCall, s.info, @[
|
||||||
useSym(destructableT.destructor), useSym(s)]))
|
useSym(destructableT.destructor, c.graph.usageSym),
|
||||||
|
useSym(s, c.graph.usageSym)]))
|
||||||
result = newNode(nkDefer, s.info, @[call])
|
result = newNode(nkDefer, s.info, @[call])
|
||||||
|
|
||||||
proc insertDestructors(c: PContext,
|
proc insertDestructors(c: PContext,
|
||||||
|
|
@ -233,8 +234,8 @@ proc insertDestructors(c: PContext,
|
||||||
tryStmt.addSon(
|
tryStmt.addSon(
|
||||||
newNode(nkFinally, info, @[
|
newNode(nkFinally, info, @[
|
||||||
semStmt(c, newNode(nkCall, info, @[
|
semStmt(c, newNode(nkCall, info, @[
|
||||||
useSym(destructableT.destructor),
|
useSym(destructableT.destructor, c.graph.usageSym),
|
||||||
useSym(varId.sym)]))]))
|
useSym(varId.sym, c.graph.usageSym)]))]))
|
||||||
|
|
||||||
result.outer = newNodeI(nkStmtList, info)
|
result.outer = newNodeI(nkStmtList, info)
|
||||||
varSection.sons.setLen(j+1)
|
varSection.sons.setLen(j+1)
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@
|
||||||
|
|
||||||
proc semTemplateExpr(c: PContext, n: PNode, s: PSym,
|
proc semTemplateExpr(c: PContext, n: PNode, s: PSym,
|
||||||
flags: TExprFlags = {}): PNode =
|
flags: TExprFlags = {}): PNode =
|
||||||
markUsed(n.info, s)
|
markUsed(n.info, s, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
pushInfoContext(n.info)
|
pushInfoContext(n.info)
|
||||||
result = evalTemplate(n, s, getCurrOwner(), efFromHlo in flags)
|
result = evalTemplate(n, s, getCurrOwner(c), efFromHlo in flags)
|
||||||
if efNoSemCheck notin flags: result = semAfterMacroCall(c, result, s, flags)
|
if efNoSemCheck notin flags: result = semAfterMacroCall(c, result, s, flags)
|
||||||
popInfoContext()
|
popInfoContext()
|
||||||
|
|
||||||
|
|
@ -209,7 +209,7 @@ proc semConv(c: PContext, n: PNode): PNode =
|
||||||
let it = op.sons[i]
|
let it = op.sons[i]
|
||||||
let status = checkConvertible(c, result.typ, it.typ)
|
let status = checkConvertible(c, result.typ, it.typ)
|
||||||
if status in {convOK, convNotNeedeed}:
|
if status in {convOK, convNotNeedeed}:
|
||||||
markUsed(n.info, it.sym)
|
markUsed(n.info, it.sym, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, it.sym)
|
styleCheckUse(n.info, it.sym)
|
||||||
markIndirect(c, it.sym)
|
markIndirect(c, it.sym)
|
||||||
return it
|
return it
|
||||||
|
|
@ -926,7 +926,7 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
|
||||||
let s = getGenSym(c, sym)
|
let s = getGenSym(c, sym)
|
||||||
case s.kind
|
case s.kind
|
||||||
of skConst:
|
of skConst:
|
||||||
markUsed(n.info, s)
|
markUsed(n.info, s, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
case skipTypes(s.typ, abstractInst-{tyTypeDesc}).kind
|
case skipTypes(s.typ, abstractInst-{tyTypeDesc}).kind
|
||||||
of tyNil, tyChar, tyInt..tyInt64, tyFloat..tyFloat128,
|
of tyNil, tyChar, tyInt..tyInt64, tyFloat..tyFloat128,
|
||||||
|
|
@ -950,20 +950,20 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
|
||||||
result = newSymNode(s, n.info)
|
result = newSymNode(s, n.info)
|
||||||
of skMacro:
|
of skMacro:
|
||||||
if efNoEvaluateGeneric in flags and s.ast[genericParamsPos].len > 0:
|
if efNoEvaluateGeneric in flags and s.ast[genericParamsPos].len > 0:
|
||||||
markUsed(n.info, s)
|
markUsed(n.info, s, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
result = newSymNode(s, n.info)
|
result = newSymNode(s, n.info)
|
||||||
else:
|
else:
|
||||||
result = semMacroExpr(c, n, n, s, flags)
|
result = semMacroExpr(c, n, n, s, flags)
|
||||||
of skTemplate:
|
of skTemplate:
|
||||||
if efNoEvaluateGeneric in flags and s.ast[genericParamsPos].len > 0:
|
if efNoEvaluateGeneric in flags and s.ast[genericParamsPos].len > 0:
|
||||||
markUsed(n.info, s)
|
markUsed(n.info, s, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
result = newSymNode(s, n.info)
|
result = newSymNode(s, n.info)
|
||||||
else:
|
else:
|
||||||
result = semTemplateExpr(c, n, s, flags)
|
result = semTemplateExpr(c, n, s, flags)
|
||||||
of skParam:
|
of skParam:
|
||||||
markUsed(n.info, s)
|
markUsed(n.info, s, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
if s.typ.kind == tyStatic and s.typ.n != nil:
|
if s.typ.kind == tyStatic and s.typ.n != nil:
|
||||||
# XXX see the hack in sigmatch.nim ...
|
# XXX see the hack in sigmatch.nim ...
|
||||||
|
|
@ -985,7 +985,7 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
|
||||||
if s.magic == mNimvm:
|
if s.magic == mNimvm:
|
||||||
localError(n.info, "illegal context for 'nimvm' magic")
|
localError(n.info, "illegal context for 'nimvm' magic")
|
||||||
|
|
||||||
markUsed(n.info, s)
|
markUsed(n.info, s, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
result = newSymNode(s, n.info)
|
result = newSymNode(s, n.info)
|
||||||
# We cannot check for access to outer vars for example because it's still
|
# We cannot check for access to outer vars for example because it's still
|
||||||
|
|
@ -1003,7 +1003,7 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
|
||||||
n.typ = s.typ
|
n.typ = s.typ
|
||||||
return n
|
return n
|
||||||
of skType:
|
of skType:
|
||||||
markUsed(n.info, s)
|
markUsed(n.info, s, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
if s.typ.kind == tyStatic and s.typ.n != nil:
|
if s.typ.kind == tyStatic and s.typ.n != nil:
|
||||||
return s.typ.n
|
return s.typ.n
|
||||||
|
|
@ -1025,7 +1025,7 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
|
||||||
if f != nil and fieldVisible(c, f):
|
if f != nil and fieldVisible(c, f):
|
||||||
# is the access to a public field or in the same module or in a friend?
|
# is the access to a public field or in the same module or in a friend?
|
||||||
doAssert f == s
|
doAssert f == s
|
||||||
markUsed(n.info, f)
|
markUsed(n.info, f, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, f)
|
styleCheckUse(n.info, f)
|
||||||
result = newNodeIT(nkDotExpr, n.info, f.typ)
|
result = newNodeIT(nkDotExpr, n.info, f.typ)
|
||||||
result.add makeDeref(newSymNode(p.selfSym))
|
result.add makeDeref(newSymNode(p.selfSym))
|
||||||
|
|
@ -1038,11 +1038,11 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
|
||||||
if ty.sons[0] == nil: break
|
if ty.sons[0] == nil: break
|
||||||
ty = skipTypes(ty.sons[0], skipPtrs)
|
ty = skipTypes(ty.sons[0], skipPtrs)
|
||||||
# old code, not sure if it's live code:
|
# old code, not sure if it's live code:
|
||||||
markUsed(n.info, s)
|
markUsed(n.info, s, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
result = newSymNode(s, n.info)
|
result = newSymNode(s, n.info)
|
||||||
else:
|
else:
|
||||||
markUsed(n.info, s)
|
markUsed(n.info, s, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
result = newSymNode(s, n.info)
|
result = newSymNode(s, n.info)
|
||||||
|
|
||||||
|
|
@ -1062,7 +1062,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
result = symChoice(c, n, s, scClosed)
|
result = symChoice(c, n, s, scClosed)
|
||||||
if result.kind == nkSym: result = semSym(c, n, s, flags)
|
if result.kind == nkSym: result = semSym(c, n, s, flags)
|
||||||
else:
|
else:
|
||||||
markUsed(n.sons[1].info, s)
|
markUsed(n.sons[1].info, s, c.graph.usageSym)
|
||||||
result = semSym(c, n, s, flags)
|
result = semSym(c, n, s, flags)
|
||||||
styleCheckUse(n.sons[1].info, s)
|
styleCheckUse(n.sons[1].info, s)
|
||||||
return
|
return
|
||||||
|
|
@ -1087,7 +1087,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
result = newSymNode(f)
|
result = newSymNode(f)
|
||||||
result.info = n.info
|
result.info = n.info
|
||||||
result.typ = ty
|
result.typ = ty
|
||||||
markUsed(n.info, f)
|
markUsed(n.info, f, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, f)
|
styleCheckUse(n.info, f)
|
||||||
return
|
return
|
||||||
of tyTypeParamsHolders:
|
of tyTypeParamsHolders:
|
||||||
|
|
@ -1120,7 +1120,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
if f != nil:
|
if f != nil:
|
||||||
if fieldVisible(c, f):
|
if fieldVisible(c, f):
|
||||||
# is the access to a public field or in the same module or in a friend?
|
# is the access to a public field or in the same module or in a friend?
|
||||||
markUsed(n.sons[1].info, f)
|
markUsed(n.sons[1].info, f, c.graph.usageSym)
|
||||||
styleCheckUse(n.sons[1].info, f)
|
styleCheckUse(n.sons[1].info, f)
|
||||||
n.sons[0] = makeDeref(n.sons[0])
|
n.sons[0] = makeDeref(n.sons[0])
|
||||||
n.sons[1] = newSymNode(f) # we now have the correct field
|
n.sons[1] = newSymNode(f) # we now have the correct field
|
||||||
|
|
@ -1134,7 +1134,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
elif ty.kind == tyTuple and ty.n != nil:
|
elif ty.kind == tyTuple and ty.n != nil:
|
||||||
f = getSymFromList(ty.n, i)
|
f = getSymFromList(ty.n, i)
|
||||||
if f != nil:
|
if f != nil:
|
||||||
markUsed(n.sons[1].info, f)
|
markUsed(n.sons[1].info, f, c.graph.usageSym)
|
||||||
styleCheckUse(n.sons[1].info, f)
|
styleCheckUse(n.sons[1].info, f)
|
||||||
n.sons[0] = makeDeref(n.sons[0])
|
n.sons[0] = makeDeref(n.sons[0])
|
||||||
n.sons[1] = newSymNode(f)
|
n.sons[1] = newSymNode(f)
|
||||||
|
|
@ -1581,9 +1581,8 @@ proc getMagicSym(magic: TMagic): PSym =
|
||||||
result = newSym(skProc, getIdent($magic), systemModule, gCodegenLineInfo)
|
result = newSym(skProc, getIdent($magic), systemModule, gCodegenLineInfo)
|
||||||
result.magic = magic
|
result.magic = magic
|
||||||
|
|
||||||
proc newAnonSym(c: PContext; kind: TSymKind, info: TLineInfo,
|
proc newAnonSym(c: PContext; kind: TSymKind, info: TLineInfo): PSym =
|
||||||
owner = getCurrOwner()): PSym =
|
result = newSym(kind, c.cache.idAnon, getCurrOwner(c), info)
|
||||||
result = newSym(kind, c.cache.idAnon, owner, info)
|
|
||||||
result.flags = {sfGenSym}
|
result.flags = {sfGenSym}
|
||||||
|
|
||||||
proc semExpandToAst(c: PContext, n: PNode): PNode =
|
proc semExpandToAst(c: PContext, n: PNode): PNode =
|
||||||
|
|
@ -1592,7 +1591,7 @@ proc semExpandToAst(c: PContext, n: PNode): PNode =
|
||||||
if expandedSym.kind == skError: return n
|
if expandedSym.kind == skError: return n
|
||||||
|
|
||||||
macroCall.sons[0] = newSymNode(expandedSym, macroCall.info)
|
macroCall.sons[0] = newSymNode(expandedSym, macroCall.info)
|
||||||
markUsed(n.info, expandedSym)
|
markUsed(n.info, expandedSym, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, expandedSym)
|
styleCheckUse(n.info, expandedSym)
|
||||||
|
|
||||||
for i in countup(1, macroCall.len-1):
|
for i in countup(1, macroCall.len-1):
|
||||||
|
|
@ -1683,7 +1682,7 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
# open a scope for temporary symbol inclusions:
|
# open a scope for temporary symbol inclusions:
|
||||||
let oldScope = c.currentScope
|
let oldScope = c.currentScope
|
||||||
openScope(c)
|
openScope(c)
|
||||||
let oldOwnerLen = len(gOwners)
|
let oldOwnerLen = len(c.graph.owners)
|
||||||
let oldGenerics = c.generics
|
let oldGenerics = c.generics
|
||||||
let oldErrorOutputs = errorOutputs
|
let oldErrorOutputs = errorOutputs
|
||||||
errorOutputs = {}
|
errorOutputs = {}
|
||||||
|
|
@ -1709,7 +1708,7 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
c.inGenericInst = oldInGenericInst
|
c.inGenericInst = oldInGenericInst
|
||||||
c.p = oldProcCon
|
c.p = oldProcCon
|
||||||
msgs.setInfoContextLen(oldContextLen)
|
msgs.setInfoContextLen(oldContextLen)
|
||||||
setLen(gOwners, oldOwnerLen)
|
setLen(c.graph.owners, oldOwnerLen)
|
||||||
c.currentScope = oldScope
|
c.currentScope = oldScope
|
||||||
errorOutputs = oldErrorOutputs
|
errorOutputs = oldErrorOutputs
|
||||||
msgs.gErrorCounter = oldErrorCount
|
msgs.gErrorCounter = oldErrorCount
|
||||||
|
|
@ -2108,7 +2107,7 @@ proc semBlock(c: PContext, n: PNode): PNode =
|
||||||
if sfGenSym notin labl.flags:
|
if sfGenSym notin labl.flags:
|
||||||
addDecl(c, labl)
|
addDecl(c, labl)
|
||||||
n.sons[0] = newSymNode(labl, n.sons[0].info)
|
n.sons[0] = newSymNode(labl, n.sons[0].info)
|
||||||
suggestSym(n.sons[0].info, labl)
|
suggestSym(n.sons[0].info, labl, c.graph.usageSym)
|
||||||
styleCheckDef(labl)
|
styleCheckDef(labl)
|
||||||
n.sons[1] = semExpr(c, n.sons[1])
|
n.sons[1] = semExpr(c, n.sons[1])
|
||||||
n.typ = n.sons[1].typ
|
n.typ = n.sons[1].typ
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
|
||||||
var trueSymbol = strTableGet(magicsys.systemModule.tab, getIdent"true")
|
var trueSymbol = strTableGet(magicsys.systemModule.tab, getIdent"true")
|
||||||
if trueSymbol == nil:
|
if trueSymbol == nil:
|
||||||
localError(n.info, errSystemNeeds, "true")
|
localError(n.info, errSystemNeeds, "true")
|
||||||
trueSymbol = newSym(skUnknown, getIdent"true", getCurrOwner(), n.info)
|
trueSymbol = newSym(skUnknown, getIdent"true", getCurrOwner(c), n.info)
|
||||||
trueSymbol.typ = getSysType(tyBool)
|
trueSymbol.typ = getSysType(tyBool)
|
||||||
|
|
||||||
result.sons[0] = newSymNode(trueSymbol, n.info)
|
result.sons[0] = newSymNode(trueSymbol, n.info)
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ iterator instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable): PSym
|
||||||
if q.typ.kind notin {tyTypeDesc, tyGenericParam, tyStatic}+tyTypeClasses:
|
if q.typ.kind notin {tyTypeDesc, tyGenericParam, tyStatic}+tyTypeClasses:
|
||||||
continue
|
continue
|
||||||
let symKind = if q.typ.kind == tyStatic: skConst else: skType
|
let symKind = if q.typ.kind == tyStatic: skConst else: skType
|
||||||
var s = newSym(symKind, q.name, getCurrOwner(), q.info)
|
var s = newSym(symKind, q.name, getCurrOwner(c), q.info)
|
||||||
s.flags = s.flags + {sfUsed, sfFromGeneric}
|
s.flags = s.flags + {sfUsed, sfFromGeneric}
|
||||||
var t = PType(idTableGet(pt, q.typ))
|
var t = PType(idTableGet(pt, q.typ))
|
||||||
if t == nil:
|
if t == nil:
|
||||||
|
|
@ -255,7 +255,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
||||||
incl(result.flags, sfFromGeneric)
|
incl(result.flags, sfFromGeneric)
|
||||||
result.owner = fn
|
result.owner = fn
|
||||||
result.ast = n
|
result.ast = n
|
||||||
pushOwner(result)
|
pushOwner(c, result)
|
||||||
|
|
||||||
openScope(c)
|
openScope(c)
|
||||||
let gp = n.sons[genericParamsPos]
|
let gp = n.sons[genericParamsPos]
|
||||||
|
|
@ -304,7 +304,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
||||||
popProcCon(c)
|
popProcCon(c)
|
||||||
popInfoContext()
|
popInfoContext()
|
||||||
closeScope(c) # close scope for parameters
|
closeScope(c) # close scope for parameters
|
||||||
popOwner()
|
popOwner(c)
|
||||||
c.currentScope = oldScope
|
c.currentScope = oldScope
|
||||||
discard c.friendModules.pop()
|
discard c.friendModules.pop()
|
||||||
dec(c.instCounter)
|
dec(c.instCounter)
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ proc semTypeTraits(c: PContext, n: PNode): PNode =
|
||||||
if t.sonsLen > 0:
|
if t.sonsLen > 0:
|
||||||
# This is either a type known to sem or a typedesc
|
# This is either a type known to sem or a typedesc
|
||||||
# param to a regular proc (again, known at instantiation)
|
# param to a regular proc (again, known at instantiation)
|
||||||
result = evalTypeTrait(n[0], t, getCurrOwner())
|
result = evalTypeTrait(n[0], t, getCurrOwner(c))
|
||||||
else:
|
else:
|
||||||
# a typedesc variable, pass unmodified to evals
|
# a typedesc variable, pass unmodified to evals
|
||||||
result = n
|
result = n
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ proc semBreakOrContinue(c: PContext, n: PNode): PNode =
|
||||||
x.info = n.info
|
x.info = n.info
|
||||||
incl(s.flags, sfUsed)
|
incl(s.flags, sfUsed)
|
||||||
n.sons[0] = x
|
n.sons[0] = x
|
||||||
suggestSym(x.info, s)
|
suggestSym(x.info, s, c.graph.usageSym)
|
||||||
styleCheckUse(x.info, s)
|
styleCheckUse(x.info, s)
|
||||||
else:
|
else:
|
||||||
localError(n.info, errInvalidControlFlowX, s.name.s)
|
localError(n.info, errInvalidControlFlowX, s.name.s)
|
||||||
|
|
@ -366,11 +366,13 @@ proc semIdentDef(c: PContext, n: PNode, kind: TSymKind): PSym =
|
||||||
if isTopLevel(c):
|
if isTopLevel(c):
|
||||||
result = semIdentWithPragma(c, kind, n, {sfExported})
|
result = semIdentWithPragma(c, kind, n, {sfExported})
|
||||||
incl(result.flags, sfGlobal)
|
incl(result.flags, sfGlobal)
|
||||||
|
#if kind in {skVar, skLet}:
|
||||||
|
# echo "global variable here ", n.info, " ", result.name.s
|
||||||
else:
|
else:
|
||||||
result = semIdentWithPragma(c, kind, n, {})
|
result = semIdentWithPragma(c, kind, n, {})
|
||||||
if result.owner.kind == skModule:
|
if result.owner.kind == skModule:
|
||||||
incl(result.flags, sfGlobal)
|
incl(result.flags, sfGlobal)
|
||||||
suggestSym(n.info, result)
|
suggestSym(n.info, result, c.graph.usageSym)
|
||||||
styleCheckDef(result)
|
styleCheckDef(result)
|
||||||
|
|
||||||
proc checkNilable(v: PSym) =
|
proc checkNilable(v: PSym) =
|
||||||
|
|
@ -621,7 +623,7 @@ proc semForVars(c: PContext, n: PNode): PNode =
|
||||||
if iter.kind != tyTuple or length == 3:
|
if iter.kind != tyTuple or length == 3:
|
||||||
if length == 3:
|
if length == 3:
|
||||||
var v = symForVar(c, n.sons[0])
|
var v = symForVar(c, n.sons[0])
|
||||||
if getCurrOwner().kind == skModule: incl(v.flags, sfGlobal)
|
if getCurrOwner(c).kind == skModule: incl(v.flags, sfGlobal)
|
||||||
# BUGFIX: don't use `iter` here as that would strip away
|
# BUGFIX: don't use `iter` here as that would strip away
|
||||||
# the ``tyGenericInst``! See ``tests/compile/tgeneric.nim``
|
# the ``tyGenericInst``! See ``tests/compile/tgeneric.nim``
|
||||||
# for an example:
|
# for an example:
|
||||||
|
|
@ -635,7 +637,7 @@ proc semForVars(c: PContext, n: PNode): PNode =
|
||||||
else:
|
else:
|
||||||
for i in countup(0, length - 3):
|
for i in countup(0, length - 3):
|
||||||
var v = symForVar(c, n.sons[i])
|
var v = symForVar(c, n.sons[i])
|
||||||
if getCurrOwner().kind == skModule: incl(v.flags, sfGlobal)
|
if getCurrOwner(c).kind == skModule: incl(v.flags, sfGlobal)
|
||||||
v.typ = iter.sons[i]
|
v.typ = iter.sons[i]
|
||||||
n.sons[i] = newSymNode(v)
|
n.sons[i] = newSymNode(v)
|
||||||
if sfGenSym notin v.flags and not isDiscardUnderscore(v):
|
if sfGenSym notin v.flags and not isDiscardUnderscore(v):
|
||||||
|
|
@ -745,7 +747,7 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
|
||||||
# We have a generic type declaration here. In generic types,
|
# We have a generic type declaration here. In generic types,
|
||||||
# symbol lookup needs to be done here.
|
# symbol lookup needs to be done here.
|
||||||
openScope(c)
|
openScope(c)
|
||||||
pushOwner(s)
|
pushOwner(c, s)
|
||||||
if s.magic == mNone: s.typ.kind = tyGenericBody
|
if s.magic == mNone: s.typ.kind = tyGenericBody
|
||||||
# XXX for generic type aliases this is not correct! We need the
|
# XXX for generic type aliases this is not correct! We need the
|
||||||
# underlying Id really:
|
# underlying Id really:
|
||||||
|
|
@ -769,11 +771,11 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
|
||||||
body.sym = s
|
body.sym = s
|
||||||
body.size = -1 # could not be computed properly
|
body.size = -1 # could not be computed properly
|
||||||
s.typ.sons[sonsLen(s.typ) - 1] = body
|
s.typ.sons[sonsLen(s.typ) - 1] = body
|
||||||
popOwner()
|
popOwner(c)
|
||||||
closeScope(c)
|
closeScope(c)
|
||||||
elif a.sons[2].kind != nkEmpty:
|
elif a.sons[2].kind != nkEmpty:
|
||||||
# process the type's body:
|
# process the type's body:
|
||||||
pushOwner(s)
|
pushOwner(c, s)
|
||||||
var t = semTypeNode(c, a.sons[2], s.typ)
|
var t = semTypeNode(c, a.sons[2], s.typ)
|
||||||
if s.typ == nil:
|
if s.typ == nil:
|
||||||
s.typ = t
|
s.typ = t
|
||||||
|
|
@ -782,7 +784,7 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
|
||||||
assignType(s.typ, t)
|
assignType(s.typ, t)
|
||||||
#debug s.typ
|
#debug s.typ
|
||||||
s.ast = a
|
s.ast = a
|
||||||
popOwner()
|
popOwner(c)
|
||||||
let aa = a.sons[2]
|
let aa = a.sons[2]
|
||||||
if aa.kind in {nkRefTy, nkPtrTy} and aa.len == 1 and
|
if aa.kind in {nkRefTy, nkPtrTy} and aa.len == 1 and
|
||||||
aa.sons[0].kind == nkObjectTy:
|
aa.sons[0].kind == nkObjectTy:
|
||||||
|
|
@ -793,7 +795,7 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
|
||||||
internalAssert st.lastSon.sym == nil
|
internalAssert st.lastSon.sym == nil
|
||||||
incl st.flags, tfRefsAnonObj
|
incl st.flags, tfRefsAnonObj
|
||||||
let obj = newSym(skType, getIdent(s.name.s & ":ObjectType"),
|
let obj = newSym(skType, getIdent(s.name.s & ":ObjectType"),
|
||||||
getCurrOwner(), s.info)
|
getCurrOwner(c), s.info)
|
||||||
obj.typ = st.lastSon
|
obj.typ = st.lastSon
|
||||||
st.lastSon.sym = obj
|
st.lastSon.sym = obj
|
||||||
|
|
||||||
|
|
@ -927,7 +929,7 @@ proc semBorrow(c: PContext, n: PNode, s: PSym) =
|
||||||
|
|
||||||
proc addResult(c: PContext, t: PType, info: TLineInfo, owner: TSymKind) =
|
proc addResult(c: PContext, t: PType, info: TLineInfo, owner: TSymKind) =
|
||||||
if t != nil:
|
if t != nil:
|
||||||
var s = newSym(skResult, getIdent"result", getCurrOwner(), info)
|
var s = newSym(skResult, getIdent"result", getCurrOwner(c), info)
|
||||||
s.typ = t
|
s.typ = t
|
||||||
incl(s.flags, sfUsed)
|
incl(s.flags, sfUsed)
|
||||||
addParamOrResult(c, s, owner)
|
addParamOrResult(c, s, owner)
|
||||||
|
|
@ -1002,12 +1004,12 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
checkSonsLen(n, bodyPos + 1)
|
checkSonsLen(n, bodyPos + 1)
|
||||||
var s: PSym
|
var s: PSym
|
||||||
if n[namePos].kind != nkSym:
|
if n[namePos].kind != nkSym:
|
||||||
s = newSym(skProc, c.cache.idAnon, getCurrOwner(), n.info)
|
s = newSym(skProc, c.cache.idAnon, getCurrOwner(c), n.info)
|
||||||
s.ast = n
|
s.ast = n
|
||||||
n.sons[namePos] = newSymNode(s)
|
n.sons[namePos] = newSymNode(s)
|
||||||
else:
|
else:
|
||||||
s = n[namePos].sym
|
s = n[namePos].sym
|
||||||
pushOwner(s)
|
pushOwner(c, s)
|
||||||
openScope(c)
|
openScope(c)
|
||||||
var gp: PNode
|
var gp: PNode
|
||||||
if n.sons[genericParamsPos].kind != nkEmpty:
|
if n.sons[genericParamsPos].kind != nkEmpty:
|
||||||
|
|
@ -1047,7 +1049,7 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
else:
|
else:
|
||||||
localError(n.info, errImplOfXexpected, s.name.s)
|
localError(n.info, errImplOfXexpected, s.name.s)
|
||||||
closeScope(c) # close scope for parameters
|
closeScope(c) # close scope for parameters
|
||||||
popOwner()
|
popOwner(c)
|
||||||
result.typ = s.typ
|
result.typ = s.typ
|
||||||
|
|
||||||
proc semDo(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
proc semDo(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
|
|
@ -1081,7 +1083,7 @@ proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode =
|
||||||
params[i].sym.name.s)
|
params[i].sym.name.s)
|
||||||
#params[i].sym.owner = s
|
#params[i].sym.owner = s
|
||||||
openScope(c)
|
openScope(c)
|
||||||
pushOwner(s)
|
pushOwner(c, s)
|
||||||
addParams(c, params, skProc)
|
addParams(c, params, skProc)
|
||||||
pushProcCon(c, s)
|
pushProcCon(c, s)
|
||||||
addResult(c, n.typ.sons[0], n.info, skProc)
|
addResult(c, n.typ.sons[0], n.info, skProc)
|
||||||
|
|
@ -1089,7 +1091,7 @@ proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode =
|
||||||
let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
|
let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
|
||||||
n.sons[bodyPos] = transformBody(c.module, semBody, s)
|
n.sons[bodyPos] = transformBody(c.module, semBody, s)
|
||||||
popProcCon(c)
|
popProcCon(c)
|
||||||
popOwner()
|
popOwner(c)
|
||||||
closeScope(c)
|
closeScope(c)
|
||||||
|
|
||||||
# alternative variant (not quite working):
|
# alternative variant (not quite working):
|
||||||
|
|
@ -1193,6 +1195,42 @@ type
|
||||||
|
|
||||||
import compilerlog
|
import compilerlog
|
||||||
|
|
||||||
|
proc hasObjParam(s: PSym): bool =
|
||||||
|
var t = s.typ
|
||||||
|
for col in countup(1, sonsLen(t)-1):
|
||||||
|
if skipTypes(t.sons[col], skipPtrs).kind == tyObject:
|
||||||
|
return true
|
||||||
|
|
||||||
|
proc finishMethod(c: PContext, s: PSym) =
|
||||||
|
if hasObjParam(s):
|
||||||
|
methodDef(c.graph, s, false)
|
||||||
|
|
||||||
|
proc semMethodPrototype(c: PContext; s: PSym; n: PNode) =
|
||||||
|
if isGenericRoutine(s):
|
||||||
|
let tt = s.typ
|
||||||
|
var foundObj = false
|
||||||
|
# we start at 1 for now so that tparsecombnum continues to compile.
|
||||||
|
# XXX Revisit this problem later.
|
||||||
|
for col in countup(1, sonsLen(tt)-1):
|
||||||
|
let t = tt.sons[col]
|
||||||
|
if t != nil and t.kind == tyGenericInvocation:
|
||||||
|
var x = skipTypes(t.sons[0], {tyVar, tyPtr, tyRef, tyGenericInst,
|
||||||
|
tyGenericInvocation, tyGenericBody,
|
||||||
|
tyAlias})
|
||||||
|
if x.kind == tyObject and t.len-1 == n.sons[genericParamsPos].len:
|
||||||
|
foundObj = true
|
||||||
|
x.methods.safeAdd((col,s))
|
||||||
|
if not foundObj:
|
||||||
|
message(n.info, warnDeprecated, "generic method not attachable to object type")
|
||||||
|
else:
|
||||||
|
# why check for the body? bug #2400 has none. Checking for sfForward makes
|
||||||
|
# no sense either.
|
||||||
|
# and result.sons[bodyPos].kind != nkEmpty:
|
||||||
|
if hasObjParam(s):
|
||||||
|
methodDef(c.graph, s, fromCache=false)
|
||||||
|
else:
|
||||||
|
localError(n.info, errXNeedsParamObjectType, "method")
|
||||||
|
|
||||||
proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||||
validPragmas: TSpecialWords,
|
validPragmas: TSpecialWords,
|
||||||
phase = stepRegisterSymbol): PNode =
|
phase = stepRegisterSymbol): PNode =
|
||||||
|
|
@ -1207,7 +1245,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||||
assert phase == stepRegisterSymbol
|
assert phase == stepRegisterSymbol
|
||||||
|
|
||||||
if n[namePos].kind == nkEmpty:
|
if n[namePos].kind == nkEmpty:
|
||||||
s = newSym(kind, c.cache.idAnon, getCurrOwner(), n.info)
|
s = newSym(kind, c.cache.idAnon, getCurrOwner(c), n.info)
|
||||||
incl(s.flags, sfUsed)
|
incl(s.flags, sfUsed)
|
||||||
isAnon = true
|
isAnon = true
|
||||||
else:
|
else:
|
||||||
|
|
@ -1224,7 +1262,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
s = n[namePos].sym
|
s = n[namePos].sym
|
||||||
s.owner = getCurrOwner()
|
s.owner = getCurrOwner(c)
|
||||||
typeIsDetermined = s.typ == nil
|
typeIsDetermined = s.typ == nil
|
||||||
s.ast = n
|
s.ast = n
|
||||||
#s.scope = c.currentScope
|
#s.scope = c.currentScope
|
||||||
|
|
@ -1233,7 +1271,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||||
# where the proc was declared
|
# where the proc was declared
|
||||||
let oldScope = c.currentScope
|
let oldScope = c.currentScope
|
||||||
#c.currentScope = s.scope
|
#c.currentScope = s.scope
|
||||||
pushOwner(s)
|
pushOwner(c, s)
|
||||||
openScope(c)
|
openScope(c)
|
||||||
var gp: PNode
|
var gp: PNode
|
||||||
if n.sons[genericParamsPos].kind != nkEmpty:
|
if n.sons[genericParamsPos].kind != nkEmpty:
|
||||||
|
|
@ -1299,8 +1337,8 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||||
if importantComments() and not isNil(proto.ast.comment):
|
if importantComments() and not isNil(proto.ast.comment):
|
||||||
n.comment = proto.ast.comment
|
n.comment = proto.ast.comment
|
||||||
proto.ast = n # needed for code generation
|
proto.ast = n # needed for code generation
|
||||||
popOwner()
|
popOwner(c)
|
||||||
pushOwner(s)
|
pushOwner(c, s)
|
||||||
s.options = gOptions
|
s.options = gOptions
|
||||||
if sfOverriden in s.flags or s.name.s[0] == '=': semOverride(c, s, n)
|
if sfOverriden in s.flags or s.name.s[0] == '=': semOverride(c, s, n)
|
||||||
if s.name.s[0] in {'.', '('}:
|
if s.name.s[0] in {'.', '('}:
|
||||||
|
|
@ -1317,6 +1355,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||||
if not usePseudoGenerics and gIdeCmd in {ideSug, ideCon} and not
|
if not usePseudoGenerics and gIdeCmd in {ideSug, ideCon} and not
|
||||||
cursorInProc(n.sons[bodyPos]):
|
cursorInProc(n.sons[bodyPos]):
|
||||||
discard "speed up nimsuggest"
|
discard "speed up nimsuggest"
|
||||||
|
if s.kind == skMethod: semMethodPrototype(c, s, n)
|
||||||
else:
|
else:
|
||||||
pushProcCon(c, s)
|
pushProcCon(c, s)
|
||||||
if n.sons[genericParamsPos].kind == nkEmpty or usePseudoGenerics:
|
if n.sons[genericParamsPos].kind == nkEmpty or usePseudoGenerics:
|
||||||
|
|
@ -1324,6 +1363,8 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||||
|
|
||||||
c.p.wasForwarded = proto != nil
|
c.p.wasForwarded = proto != nil
|
||||||
maybeAddResult(c, s, n)
|
maybeAddResult(c, s, n)
|
||||||
|
if s.kind == skMethod: semMethodPrototype(c, s, n)
|
||||||
|
|
||||||
if lfDynamicLib notin s.loc.flags:
|
if lfDynamicLib notin s.loc.flags:
|
||||||
# no semantic checking for importc:
|
# no semantic checking for importc:
|
||||||
let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
|
let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
|
||||||
|
|
@ -1333,15 +1374,18 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||||
else:
|
else:
|
||||||
if s.typ.sons[0] != nil and kind != skIterator:
|
if s.typ.sons[0] != nil and kind != skIterator:
|
||||||
addDecl(c, newSym(skUnknown, getIdent"result", nil, n.info))
|
addDecl(c, newSym(skUnknown, getIdent"result", nil, n.info))
|
||||||
|
|
||||||
openScope(c)
|
openScope(c)
|
||||||
n.sons[bodyPos] = semGenericStmt(c, n.sons[bodyPos])
|
n.sons[bodyPos] = semGenericStmt(c, n.sons[bodyPos])
|
||||||
closeScope(c)
|
closeScope(c)
|
||||||
fixupInstantiatedSymbols(c, s)
|
fixupInstantiatedSymbols(c, s)
|
||||||
|
if s.kind == skMethod: semMethodPrototype(c, s, n)
|
||||||
if sfImportc in s.flags:
|
if sfImportc in s.flags:
|
||||||
# so we just ignore the body after semantic checking for importc:
|
# so we just ignore the body after semantic checking for importc:
|
||||||
n.sons[bodyPos] = ast.emptyNode
|
n.sons[bodyPos] = ast.emptyNode
|
||||||
popProcCon(c)
|
popProcCon(c)
|
||||||
else:
|
else:
|
||||||
|
if s.kind == skMethod: semMethodPrototype(c, s, n)
|
||||||
if proto != nil: localError(n.info, errImplOfXexpected, proto.name.s)
|
if proto != nil: localError(n.info, errImplOfXexpected, proto.name.s)
|
||||||
if {sfImportc, sfBorrow} * s.flags == {} and s.magic == mNone:
|
if {sfImportc, sfBorrow} * s.flags == {} and s.magic == mNone:
|
||||||
incl(s.flags, sfForward)
|
incl(s.flags, sfForward)
|
||||||
|
|
@ -1349,7 +1393,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||||
sideEffectsCheck(c, s)
|
sideEffectsCheck(c, s)
|
||||||
closeScope(c) # close scope for parameters
|
closeScope(c) # close scope for parameters
|
||||||
# c.currentScope = oldScope
|
# c.currentScope = oldScope
|
||||||
popOwner()
|
popOwner(c)
|
||||||
if n.sons[patternPos].kind != nkEmpty:
|
if n.sons[patternPos].kind != nkEmpty:
|
||||||
c.patterns.add(s)
|
c.patterns.add(s)
|
||||||
if isAnon: result.typ = s.typ
|
if isAnon: result.typ = s.typ
|
||||||
|
|
@ -1368,7 +1412,7 @@ proc semIterator(c: PContext, n: PNode): PNode =
|
||||||
let isAnon = n[namePos].kind == nkEmpty
|
let isAnon = n[namePos].kind == nkEmpty
|
||||||
if n[namePos].kind == nkSym:
|
if n[namePos].kind == nkSym:
|
||||||
# gensym'ed iterators might need to become closure iterators:
|
# gensym'ed iterators might need to become closure iterators:
|
||||||
n[namePos].sym.owner = getCurrOwner()
|
n[namePos].sym.owner = getCurrOwner(c)
|
||||||
n[namePos].sym.kind = skIterator
|
n[namePos].sym.kind = skIterator
|
||||||
result = semProcAux(c, n, skIterator, iteratorPragmas)
|
result = semProcAux(c, n, skIterator, iteratorPragmas)
|
||||||
var s = result.sons[namePos].sym
|
var s = result.sons[namePos].sym
|
||||||
|
|
@ -1395,46 +1439,9 @@ proc semIterator(c: PContext, n: PNode): PNode =
|
||||||
proc semProc(c: PContext, n: PNode): PNode =
|
proc semProc(c: PContext, n: PNode): PNode =
|
||||||
result = semProcAux(c, n, skProc, procPragmas)
|
result = semProcAux(c, n, skProc, procPragmas)
|
||||||
|
|
||||||
proc hasObjParam(s: PSym): bool =
|
|
||||||
var t = s.typ
|
|
||||||
for col in countup(1, sonsLen(t)-1):
|
|
||||||
if skipTypes(t.sons[col], skipPtrs).kind == tyObject:
|
|
||||||
return true
|
|
||||||
|
|
||||||
proc finishMethod(c: PContext, s: PSym) =
|
|
||||||
if hasObjParam(s):
|
|
||||||
methodDef(s, false)
|
|
||||||
|
|
||||||
proc semMethod(c: PContext, n: PNode): PNode =
|
proc semMethod(c: PContext, n: PNode): PNode =
|
||||||
if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "method")
|
if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "method")
|
||||||
result = semProcAux(c, n, skMethod, methodPragmas)
|
result = semProcAux(c, n, skMethod, methodPragmas)
|
||||||
# macros can transform methods to nothing:
|
|
||||||
if namePos >= result.safeLen: return result
|
|
||||||
var s = result.sons[namePos].sym
|
|
||||||
if isGenericRoutine(s):
|
|
||||||
let tt = s.typ
|
|
||||||
var foundObj = false
|
|
||||||
# we start at 1 for now so that tparsecombnum continues to compile.
|
|
||||||
# XXX Revisit this problem later.
|
|
||||||
for col in countup(1, sonsLen(tt)-1):
|
|
||||||
let t = tt.sons[col]
|
|
||||||
if t != nil and t.kind == tyGenericInvocation:
|
|
||||||
var x = skipTypes(t.sons[0], {tyVar, tyPtr, tyRef, tyGenericInst,
|
|
||||||
tyGenericInvocation, tyGenericBody,
|
|
||||||
tyAlias})
|
|
||||||
if x.kind == tyObject and t.len-1 == result.sons[genericParamsPos].len:
|
|
||||||
foundObj = true
|
|
||||||
x.methods.safeAdd((col,s))
|
|
||||||
if not foundObj:
|
|
||||||
message(n.info, warnDeprecated, "generic method not attachable to object type")
|
|
||||||
else:
|
|
||||||
# why check for the body? bug #2400 has none. Checking for sfForward makes
|
|
||||||
# no sense either.
|
|
||||||
# and result.sons[bodyPos].kind != nkEmpty:
|
|
||||||
if hasObjParam(s):
|
|
||||||
methodDef(s, fromCache=false)
|
|
||||||
else:
|
|
||||||
localError(n.info, errXNeedsParamObjectType, "method")
|
|
||||||
|
|
||||||
proc semConverterDef(c: PContext, n: PNode): PNode =
|
proc semConverterDef(c: PContext, n: PNode): PNode =
|
||||||
if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "converter")
|
if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "converter")
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ proc symChoice(c: PContext, n: PNode, s: PSym, r: TSymChoiceRule): PNode =
|
||||||
# (s.kind notin routineKinds or s.magic != mNone):
|
# (s.kind notin routineKinds or s.magic != mNone):
|
||||||
# for instance 'nextTry' is both in tables.nim and astalgo.nim ...
|
# for instance 'nextTry' is both in tables.nim and astalgo.nim ...
|
||||||
result = newSymNode(s, n.info)
|
result = newSymNode(s, n.info)
|
||||||
markUsed(n.info, s)
|
markUsed(n.info, s, c.graph.usageSym)
|
||||||
else:
|
else:
|
||||||
# semantic checking requires a type; ``fitNode`` deals with it
|
# semantic checking requires a type; ``fitNode`` deals with it
|
||||||
# appropriately
|
# appropriately
|
||||||
|
|
@ -559,7 +559,7 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
|
||||||
styleCheckDef(s)
|
styleCheckDef(s)
|
||||||
# check parameter list:
|
# check parameter list:
|
||||||
#s.scope = c.currentScope
|
#s.scope = c.currentScope
|
||||||
pushOwner(s)
|
pushOwner(c, s)
|
||||||
openScope(c)
|
openScope(c)
|
||||||
n.sons[namePos] = newSymNode(s, n.sons[namePos].info)
|
n.sons[namePos] = newSymNode(s, n.sons[namePos].info)
|
||||||
if n.sons[pragmasPos].kind != nkEmpty:
|
if n.sons[pragmasPos].kind != nkEmpty:
|
||||||
|
|
@ -613,7 +613,7 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
|
||||||
# only parameters are resolved, no type checking is performed
|
# only parameters are resolved, no type checking is performed
|
||||||
semIdeForTemplateOrGeneric(c, n.sons[bodyPos], ctx.cursorInBody)
|
semIdeForTemplateOrGeneric(c, n.sons[bodyPos], ctx.cursorInBody)
|
||||||
closeScope(c)
|
closeScope(c)
|
||||||
popOwner()
|
popOwner(c)
|
||||||
s.ast = n
|
s.ast = n
|
||||||
result = n
|
result = n
|
||||||
if n.sons[bodyPos].kind == nkEmpty:
|
if n.sons[bodyPos].kind == nkEmpty:
|
||||||
|
|
@ -758,7 +758,7 @@ proc semPattern(c: PContext, n: PNode): PNode =
|
||||||
ctx.toMixin = initIntSet()
|
ctx.toMixin = initIntSet()
|
||||||
ctx.toInject = initIntSet()
|
ctx.toInject = initIntSet()
|
||||||
ctx.c = c
|
ctx.c = c
|
||||||
ctx.owner = getCurrOwner()
|
ctx.owner = getCurrOwner(c)
|
||||||
result = flattenStmts(semPatternBody(ctx, n))
|
result = flattenStmts(semPatternBody(ctx, n))
|
||||||
if result.kind in {nkStmtList, nkStmtListExpr}:
|
if result.kind in {nkStmtList, nkStmtListExpr}:
|
||||||
if result.len == 1:
|
if result.len == 1:
|
||||||
|
|
|
||||||
|
|
@ -306,7 +306,7 @@ proc semTypeIdent(c: PContext, n: PNode): PSym =
|
||||||
else:
|
else:
|
||||||
result = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared})
|
result = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared})
|
||||||
if result != nil:
|
if result != nil:
|
||||||
markUsed(n.info, result)
|
markUsed(n.info, result, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, result)
|
styleCheckUse(n.info, result)
|
||||||
if result.kind == skParam and result.typ.kind == tyTypeDesc:
|
if result.kind == skParam and result.typ.kind == tyTypeDesc:
|
||||||
# This is a typedesc param. is it already bound?
|
# This is a typedesc param. is it already bound?
|
||||||
|
|
@ -608,7 +608,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
||||||
let rec = rectype.sym
|
let rec = rectype.sym
|
||||||
for i in countup(0, sonsLen(n)-3):
|
for i in countup(0, sonsLen(n)-3):
|
||||||
var f = semIdentWithPragma(c, skField, n.sons[i], {sfExported})
|
var f = semIdentWithPragma(c, skField, n.sons[i], {sfExported})
|
||||||
suggestSym(n.sons[i].info, f)
|
suggestSym(n.sons[i].info, f, c.graph.usageSym)
|
||||||
f.typ = typ
|
f.typ = typ
|
||||||
f.position = pos
|
f.position = pos
|
||||||
if (rec != nil) and ({sfImportc, sfExportc} * rec.flags != {}) and
|
if (rec != nil) and ({sfImportc, sfExportc} * rec.flags != {}) and
|
||||||
|
|
@ -750,7 +750,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||||
return genericParams.sons[i].typ
|
return genericParams.sons[i].typ
|
||||||
|
|
||||||
let owner = if typeClass.sym != nil: typeClass.sym
|
let owner = if typeClass.sym != nil: typeClass.sym
|
||||||
else: getCurrOwner()
|
else: getCurrOwner(c)
|
||||||
var s = newSym(skType, finalTypId, owner, info)
|
var s = newSym(skType, finalTypId, owner, info)
|
||||||
if typId == nil: s.flags.incl(sfAnon)
|
if typId == nil: s.flags.incl(sfAnon)
|
||||||
s.linkTo(typeClass)
|
s.linkTo(typeClass)
|
||||||
|
|
@ -850,7 +850,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||||
|
|
||||||
of tyGenericInst:
|
of tyGenericInst:
|
||||||
if paramType.lastSon.kind == tyUserTypeClass:
|
if paramType.lastSon.kind == tyUserTypeClass:
|
||||||
var cp = copyType(paramType, getCurrOwner(), false)
|
var cp = copyType(paramType, getCurrOwner(c), false)
|
||||||
cp.kind = tyUserTypeClassInst
|
cp.kind = tyUserTypeClassInst
|
||||||
return addImplicitGeneric(cp)
|
return addImplicitGeneric(cp)
|
||||||
|
|
||||||
|
|
@ -876,10 +876,10 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||||
result = liftingWalk(expanded, true)
|
result = liftingWalk(expanded, true)
|
||||||
|
|
||||||
of tyUserTypeClass, tyBuiltInTypeClass, tyAnd, tyOr, tyNot:
|
of tyUserTypeClass, tyBuiltInTypeClass, tyAnd, tyOr, tyNot:
|
||||||
result = addImplicitGeneric(copyType(paramType, getCurrOwner(), true))
|
result = addImplicitGeneric(copyType(paramType, getCurrOwner(c), true))
|
||||||
|
|
||||||
of tyGenericParam:
|
of tyGenericParam:
|
||||||
markUsed(info, paramType.sym)
|
markUsed(info, paramType.sym, c.graph.usageSym)
|
||||||
styleCheckUse(info, paramType.sym)
|
styleCheckUse(info, paramType.sym)
|
||||||
if tfWildcard in paramType.flags:
|
if tfWildcard in paramType.flags:
|
||||||
paramType.flags.excl tfWildcard
|
paramType.flags.excl tfWildcard
|
||||||
|
|
@ -1267,7 +1267,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
of mExpr:
|
of mExpr:
|
||||||
result = semTypeNode(c, n.sons[0], nil)
|
result = semTypeNode(c, n.sons[0], nil)
|
||||||
if result != nil:
|
if result != nil:
|
||||||
result = copyType(result, getCurrOwner(), false)
|
result = copyType(result, getCurrOwner(c), false)
|
||||||
for i in countup(1, n.len - 1):
|
for i in countup(1, n.len - 1):
|
||||||
result.rawAddSon(semTypeNode(c, n.sons[i], nil))
|
result.rawAddSon(semTypeNode(c, n.sons[i], nil))
|
||||||
of mDistinct:
|
of mDistinct:
|
||||||
|
|
@ -1330,7 +1330,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
else:
|
else:
|
||||||
assignType(prev, t)
|
assignType(prev, t)
|
||||||
result = prev
|
result = prev
|
||||||
markUsed(n.info, n.sym)
|
markUsed(n.info, n.sym, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, n.sym)
|
styleCheckUse(n.info, n.sym)
|
||||||
else:
|
else:
|
||||||
if s.kind != skError: localError(n.info, errTypeExpected)
|
if s.kind != skError: localError(n.info, errTypeExpected)
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ type
|
||||||
const
|
const
|
||||||
isNilConversion = isConvertible # maybe 'isIntConv' fits better?
|
isNilConversion = isConvertible # maybe 'isIntConv' fits better?
|
||||||
|
|
||||||
proc markUsed*(info: TLineInfo, s: PSym)
|
proc markUsed*(info: TLineInfo, s: PSym; usageSym: var PSym)
|
||||||
|
|
||||||
template hasFauxMatch*(c: TCandidate): bool = c.fauxMatch != tyNone
|
template hasFauxMatch*(c: TCandidate): bool = c.fauxMatch != tyNone
|
||||||
|
|
||||||
|
|
@ -1291,7 +1291,7 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType,
|
||||||
dest = generateTypeInstance(c, m.bindings, arg, dest)
|
dest = generateTypeInstance(c, m.bindings, arg, dest)
|
||||||
let fdest = typeRel(m, f, dest)
|
let fdest = typeRel(m, f, dest)
|
||||||
if fdest in {isEqual, isGeneric}:
|
if fdest in {isEqual, isGeneric}:
|
||||||
markUsed(arg.info, c.converters[i])
|
markUsed(arg.info, c.converters[i], c.graph.usageSym)
|
||||||
var s = newSymNode(c.converters[i])
|
var s = newSymNode(c.converters[i])
|
||||||
s.typ = c.converters[i].typ
|
s.typ = c.converters[i].typ
|
||||||
s.info = arg.info
|
s.info = arg.info
|
||||||
|
|
@ -1551,7 +1551,7 @@ proc paramTypesMatch*(m: var TCandidate, f, a: PType,
|
||||||
else: result = nil
|
else: result = nil
|
||||||
else:
|
else:
|
||||||
# only one valid interpretation found:
|
# only one valid interpretation found:
|
||||||
markUsed(arg.info, arg.sons[best].sym)
|
markUsed(arg.info, arg.sons[best].sym, m.c.graph.usageSym)
|
||||||
styleCheckUse(arg.info, arg.sons[best].sym)
|
styleCheckUse(arg.info, arg.sons[best].sym)
|
||||||
result = paramTypesMatchAux(m, f, arg.sons[best].typ, arg.sons[best],
|
result = paramTypesMatchAux(m, f, arg.sons[best].typ, arg.sons[best],
|
||||||
argOrig)
|
argOrig)
|
||||||
|
|
|
||||||
|
|
@ -353,10 +353,10 @@ when defined(nimsuggest):
|
||||||
s.allUsages.add(info)
|
s.allUsages.add(info)
|
||||||
|
|
||||||
var
|
var
|
||||||
usageSym*: PSym
|
#usageSym*: PSym
|
||||||
lastLineInfo*: TLineInfo
|
lastLineInfo*: TLineInfo
|
||||||
|
|
||||||
proc findUsages(info: TLineInfo; s: PSym) =
|
proc findUsages(info: TLineInfo; s: PSym; usageSym: var PSym) =
|
||||||
if suggestVersion < 2:
|
if suggestVersion < 2:
|
||||||
if usageSym == nil and isTracked(info, s.name.s.len):
|
if usageSym == nil and isTracked(info, s.name.s.len):
|
||||||
usageSym = s
|
usageSym = s
|
||||||
|
|
@ -385,7 +385,7 @@ proc ensureIdx[T](x: var T, y: int) =
|
||||||
proc ensureSeq[T](x: var seq[T]) =
|
proc ensureSeq[T](x: var seq[T]) =
|
||||||
if x == nil: newSeq(x, 0)
|
if x == nil: newSeq(x, 0)
|
||||||
|
|
||||||
proc suggestSym*(info: TLineInfo; s: PSym; isDecl=true) {.inline.} =
|
proc suggestSym*(info: TLineInfo; s: PSym; usageSym: var PSym; isDecl=true) {.inline.} =
|
||||||
## misnamed: should be 'symDeclared'
|
## misnamed: should be 'symDeclared'
|
||||||
when defined(nimsuggest):
|
when defined(nimsuggest):
|
||||||
if suggestVersion == 2:
|
if suggestVersion == 2:
|
||||||
|
|
@ -395,20 +395,20 @@ proc suggestSym*(info: TLineInfo; s: PSym; isDecl=true) {.inline.} =
|
||||||
s.addNoDup(info)
|
s.addNoDup(info)
|
||||||
|
|
||||||
if gIdeCmd == ideUse:
|
if gIdeCmd == ideUse:
|
||||||
findUsages(info, s)
|
findUsages(info, s, usageSym)
|
||||||
elif gIdeCmd == ideDef:
|
elif gIdeCmd == ideDef:
|
||||||
findDefinition(info, s)
|
findDefinition(info, s)
|
||||||
elif gIdeCmd == ideDus and s != nil:
|
elif gIdeCmd == ideDus and s != nil:
|
||||||
if isTracked(info, s.name.s.len):
|
if isTracked(info, s.name.s.len):
|
||||||
suggestResult(symToSuggest(s, isLocal=false, $ideDef, 100))
|
suggestResult(symToSuggest(s, isLocal=false, $ideDef, 100))
|
||||||
findUsages(info, s)
|
findUsages(info, s, usageSym)
|
||||||
elif gIdeCmd == ideHighlight and info.fileIndex == gTrackPos.fileIndex:
|
elif gIdeCmd == ideHighlight and info.fileIndex == gTrackPos.fileIndex:
|
||||||
suggestResult(symToSuggest(s, isLocal=false, $ideHighlight, info, 100))
|
suggestResult(symToSuggest(s, isLocal=false, $ideHighlight, info, 100))
|
||||||
elif gIdeCmd == ideOutline and info.fileIndex == gTrackPos.fileIndex and
|
elif gIdeCmd == ideOutline and info.fileIndex == gTrackPos.fileIndex and
|
||||||
isDecl:
|
isDecl:
|
||||||
suggestResult(symToSuggest(s, isLocal=false, $ideOutline, info, 100))
|
suggestResult(symToSuggest(s, isLocal=false, $ideOutline, info, 100))
|
||||||
|
|
||||||
proc markUsed(info: TLineInfo; s: PSym) =
|
proc markUsed(info: TLineInfo; s: PSym; usageSym: var PSym) =
|
||||||
incl(s.flags, sfUsed)
|
incl(s.flags, sfUsed)
|
||||||
if s.kind == skEnumField and s.owner != nil:
|
if s.kind == skEnumField and s.owner != nil:
|
||||||
incl(s.owner.flags, sfUsed)
|
incl(s.owner.flags, sfUsed)
|
||||||
|
|
@ -416,11 +416,11 @@ proc markUsed(info: TLineInfo; s: PSym) =
|
||||||
if sfDeprecated in s.flags: message(info, warnDeprecated, s.name.s)
|
if sfDeprecated in s.flags: message(info, warnDeprecated, s.name.s)
|
||||||
if sfError in s.flags: localError(info, errWrongSymbolX, s.name.s)
|
if sfError in s.flags: localError(info, errWrongSymbolX, s.name.s)
|
||||||
when defined(nimsuggest):
|
when defined(nimsuggest):
|
||||||
suggestSym(info, s, false)
|
suggestSym(info, s, usageSym, false)
|
||||||
|
|
||||||
proc useSym*(sym: PSym): PNode =
|
proc useSym*(sym: PSym; usageSym: var PSym): PNode =
|
||||||
result = newSymNode(sym)
|
result = newSymNode(sym)
|
||||||
markUsed(result.info, sym)
|
markUsed(result.info, sym, usageSym)
|
||||||
|
|
||||||
proc safeSemExpr*(c: PContext, n: PNode): PNode =
|
proc safeSemExpr*(c: PContext, n: PNode): PNode =
|
||||||
# use only for idetools support!
|
# use only for idetools support!
|
||||||
|
|
|
||||||
|
|
@ -694,6 +694,7 @@ proc transformCall(c: PTransf, n: PNode): PTransNode =
|
||||||
# bugfix: check after 'transformSons' if it's still a method call:
|
# bugfix: check after 'transformSons' if it's still a method call:
|
||||||
# use the dispatcher for the call:
|
# use the dispatcher for the call:
|
||||||
if s.sons[0].kind == nkSym and s.sons[0].sym.kind == skMethod:
|
if s.sons[0].kind == nkSym and s.sons[0].sym.kind == skMethod:
|
||||||
|
when false:
|
||||||
let t = lastSon(s.sons[0].sym.ast)
|
let t = lastSon(s.sons[0].sym.ast)
|
||||||
if t.kind != nkSym or sfDispatcher notin t.sym.flags:
|
if t.kind != nkSym or sfDispatcher notin t.sym.flags:
|
||||||
methodDef(s.sons[0].sym, false)
|
methodDef(s.sons[0].sym, false)
|
||||||
|
|
|
||||||
|
|
@ -1556,7 +1556,10 @@ proc myProcess(c: PPassContext, n: PNode): PNode =
|
||||||
result = n
|
result = n
|
||||||
oldErrorCount = msgs.gErrorCounter
|
oldErrorCount = msgs.gErrorCounter
|
||||||
|
|
||||||
const evalPass* = makePass(myOpen, nil, myProcess, myProcess)
|
proc myClose(graph: ModuleGraph; c: PPassContext, n: PNode): PNode =
|
||||||
|
myProcess(c, n)
|
||||||
|
|
||||||
|
const evalPass* = makePass(myOpen, nil, myProcess, myClose)
|
||||||
|
|
||||||
proc evalConstExprAux(module: PSym; cache: IdentCache; prc: PSym, n: PNode,
|
proc evalConstExprAux(module: PSym; cache: IdentCache; prc: PSym, n: PNode,
|
||||||
mode: TEvalMode): PNode =
|
mode: TEvalMode): PNode =
|
||||||
|
|
|
||||||
|
|
@ -29,10 +29,10 @@ method runInput[T, O](self: Parser[T, O], inp: Input[T]): Result[T, O] =
|
||||||
# XXX: above needed for now, as without the `tmp` bit below, it compiles to invalid C.
|
# XXX: above needed for now, as without the `tmp` bit below, it compiles to invalid C.
|
||||||
tmp(self)(inp)
|
tmp(self)(inp)
|
||||||
|
|
||||||
method run*[T, O](self: Parser[T, O], toks: seq[T]): Result[T, O] =
|
proc run*[T, O](self: Parser[T, O], toks: seq[T]): Result[T, O] =
|
||||||
self.runInput(Input[T](toks: toks, index: 0))
|
self.runInput(Input[T](toks: toks, index: 0))
|
||||||
|
|
||||||
method chain*[T, O1, O2](self: Parser[T, O1], nextp: proc (v: O1): Parser[T, O2]): Parser[T, O2] =
|
proc chain*[T, O1, O2](self: Parser[T, O1], nextp: proc (v: O1): Parser[T, O2]): Parser[T, O2] =
|
||||||
result = proc (inp: Input[T]): Result[T, O2] =
|
result = proc (inp: Input[T]): Result[T, O2] =
|
||||||
let r = self.runInput(inp)
|
let r = self.runInput(inp)
|
||||||
case r.kind:
|
case r.kind:
|
||||||
|
|
@ -41,7 +41,7 @@ method chain*[T, O1, O2](self: Parser[T, O1], nextp: proc (v: O1): Parser[T, O2]
|
||||||
of rkFailure:
|
of rkFailure:
|
||||||
Result[T, O2](kind: rkFailure)
|
Result[T, O2](kind: rkFailure)
|
||||||
|
|
||||||
method skip[T](self: Input[T], n: int): Input[T] =
|
method skip[T](self: Input[T], n: int): Input[T] {.base.} =
|
||||||
Input[T](toks: self.toks, index: self.index + n)
|
Input[T](toks: self.toks, index: self.index + n)
|
||||||
|
|
||||||
proc pskip*[T](n: int): Parser[T, tuple[]] =
|
proc pskip*[T](n: int): Parser[T, tuple[]] =
|
||||||
|
|
@ -69,11 +69,11 @@ proc `+`*[T, O](first: Parser[T, O], second: Parser[T, O]): Parser[T, O] =
|
||||||
|
|
||||||
# end of primitives (definitions involving Parser(..))
|
# end of primitives (definitions involving Parser(..))
|
||||||
|
|
||||||
method map*[T, O1, O2](self: Parser[T, O1], p: proc (v: O1): O2): Parser[T, O2] =
|
proc map*[T, O1, O2](self: Parser[T, O1], p: proc (v: O1): O2): Parser[T, O2] =
|
||||||
self.chain(proc (v: O1): Parser[T, O2] =
|
self.chain(proc (v: O1): Parser[T, O2] =
|
||||||
unit[T, O2](p(v)))
|
unit[T, O2](p(v)))
|
||||||
|
|
||||||
method then*[T, O1, O2](self: Parser[T, O1], next: Parser[T, O2]): Parser[T, O2] =
|
proc then*[T, O1, O2](self: Parser[T, O1], next: Parser[T, O2]): Parser[T, O2] =
|
||||||
self.chain(proc (v: O1): Parser[T, O2] =
|
self.chain(proc (v: O1): Parser[T, O2] =
|
||||||
next)
|
next)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue