This commit is contained in:
Andreas Rumpf
2019-08-08 21:41:05 +02:00
parent e3c0bf48c5
commit 04708742e7
5 changed files with 76 additions and 27 deletions

View File

@@ -31,7 +31,7 @@ proc importPureEnumField*(c: PContext; s: PSym) =
incl(c.ambiguousSymbols, checkB.id)
incl(c.ambiguousSymbols, s.id)
proc rawImportSymbol(c: PContext, s: PSym) =
proc rawImportSymbol(c: PContext, s, origin: PSym) =
# This does not handle stubs, because otherwise loading on demand would be
# pointless in practice. So importing stubs is fine here!
# check if we have already a symbol of the same name:
@@ -63,13 +63,14 @@ proc rawImportSymbol(c: PContext, s: PSym) =
check = nextIdentIter(it, c.importTable.symbols)
if e != nil:
if sfPure notin s.flags:
rawImportSymbol(c, e)
rawImportSymbol(c, e, origin)
else:
importPureEnumField(c, e)
else:
# rodgen assures that converters and patterns are no stubs
if s.kind == skConverter: addConverter(c, s)
if hasPattern(s): addPattern(c, s)
if s.owner != origin:
c.exportIndirections.incl(idPairToInt(origin.id, s.id))
proc importSymbol(c: PContext, n: PNode, fromMod: PSym) =
let ident = lookups.considerQuotedIdent(c, n)
@@ -88,10 +89,10 @@ proc importSymbol(c: PContext, n: PNode, fromMod: PSym) =
while e != nil:
if e.name.id != s.name.id: internalError(c.config, n.info, "importSymbol: 3")
if s.kind in ExportableSymKinds:
rawImportSymbol(c, e)
rawImportSymbol(c, e, fromMod)
e = nextIdentIter(it, fromMod.tab)
else:
rawImportSymbol(c, s)
rawImportSymbol(c, s, fromMod)
suggestSym(c.config, n.info, s, c.graph.usageSym, false)
proc importAllSymbolsExcept(c: PContext, fromMod: PSym, exceptSet: IntSet) =
@@ -103,14 +104,14 @@ proc importAllSymbolsExcept(c: PContext, fromMod: PSym, exceptSet: IntSet) =
if s.kind notin ExportableSymKinds:
internalError(c.config, s.info, "importAllSymbols: " & $s.kind & " " & s.name.s)
if exceptSet.isNil or s.name.id notin exceptSet:
rawImportSymbol(c, s)
rawImportSymbol(c, s, fromMod)
s = nextIter(i, fromMod.tab)
proc importAllSymbols*(c: PContext, fromMod: PSym) =
var exceptSet: IntSet
importAllSymbolsExcept(c, fromMod, exceptSet)
proc importForwarded(c: PContext, n: PNode, exceptSet: IntSet) =
proc importForwarded(c: PContext, n: PNode, exceptSet: IntSet; fromMod: PSym) =
if n.isNil: return
case n.kind
of nkExportStmt:
@@ -120,12 +121,12 @@ proc importForwarded(c: PContext, n: PNode, exceptSet: IntSet) =
if s.kind == skModule:
importAllSymbolsExcept(c, s, exceptSet)
elif exceptSet.isNil or s.name.id notin exceptSet:
rawImportSymbol(c, s)
rawImportSymbol(c, s, fromMod)
of nkExportExceptStmt:
localError(c.config, n.info, "'export except' not implemented")
else:
for i in 0..safeLen(n)-1:
importForwarded(c, n.sons[i], exceptSet)
importForwarded(c, n.sons[i], exceptSet, fromMod)
proc importModuleAs(c: PContext; n: PNode, realModule: PSym): PSym =
result = realModule
@@ -186,7 +187,7 @@ proc impMod(c: PContext; it: PNode; importStmtResult: PNode) =
# ``addDecl`` needs to be done before ``importAllSymbols``!
addDecl(c, m, it.info) # add symbol to symbol table of module
importAllSymbolsExcept(c, m, emptySet)
#importForwarded(c, m.ast, emptySet)
#importForwarded(c, m.ast, emptySet, m)
proc evalImport*(c: PContext, n: PNode): PNode =
result = newNodeI(nkImportStmt, n.info)
@@ -233,4 +234,4 @@ proc evalImportExcept*(c: PContext, n: PNode): PNode =
n.sons[0] = newSymNode(m)
addDecl(c, m, n.info) # add symbol to symbol table of module
importAllSymbolsExcept(c, m, readExceptSet(c, n))
#importForwarded(c, m.ast, exceptSet)
#importForwarded(c, m.ast, exceptSet, m)

View File

@@ -138,6 +138,9 @@ type
# tests/destructor/topttree.nim for an example that
# would otherwise fail.
unusedImports*: seq[(PSym, TLineInfo)]
exportIndirections*: IntSet
template idPairToInt*(a, b: int): int = a * 10_000_000 + b
template config*(c: PContext): ConfigRef = c.graph.config

View File

@@ -2130,30 +2130,42 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
result = n
case s.magic # magics that need special treatment
of mAddr:
markUsed(c, n.info, s, c.graph.usageSym)
checkSonsLen(n, 2, c.config)
result[0] = newSymNode(s, n[0].info)
result[1] = semAddrArg(c, n.sons[1], s.name.s == "unsafeAddr")
result.typ = makePtrType(c, result[1].typ)
of mTypeOf:
markUsed(c, n.info, s, c.graph.usageSym)
result = semTypeOf(c, n)
#of mArrGet: result = semArrGet(c, n, flags)
#of mArrPut: result = semArrPut(c, n, flags)
#of mAsgn: result = semAsgnOpr(c, n)
of mDefined: result = semDefined(c, setMs(n, s), false)
of mDefinedInScope: result = semDefined(c, setMs(n, s), true)
of mCompiles: result = semCompiles(c, setMs(n, s), flags)
#of mLow: result = semLowHigh(c, setMs(n, s), mLow)
#of mHigh: result = semLowHigh(c, setMs(n, s), mHigh)
of mIs: result = semIs(c, setMs(n, s), flags)
#of mOf: result = semOf(c, setMs(n, s))
of mShallowCopy: result = semShallowCopy(c, n, flags)
of mExpandToAst: result = semExpandToAst(c, n, s, flags)
of mQuoteAst: result = semQuoteAst(c, n)
of mDefined:
markUsed(c, n.info, s, c.graph.usageSym)
result = semDefined(c, setMs(n, s), false)
of mDefinedInScope:
markUsed(c, n.info, s, c.graph.usageSym)
result = semDefined(c, setMs(n, s), true)
of mCompiles:
markUsed(c, n.info, s, c.graph.usageSym)
result = semCompiles(c, setMs(n, s), flags)
of mIs:
markUsed(c, n.info, s, c.graph.usageSym)
result = semIs(c, setMs(n, s), flags)
of mShallowCopy:
markUsed(c, n.info, s, c.graph.usageSym)
result = semShallowCopy(c, n, flags)
of mExpandToAst:
markUsed(c, n.info, s, c.graph.usageSym)
result = semExpandToAst(c, n, s, flags)
of mQuoteAst:
markUsed(c, n.info, s, c.graph.usageSym)
result = semQuoteAst(c, n)
of mAstToStr:
markUsed(c, n.info, s, c.graph.usageSym)
checkSonsLen(n, 2, c.config)
result = newStrNodeT(renderTree(n[1], {renderNoComments}), n, c.graph)
result.typ = getSysType(c.graph, n.info, tyString)
of mParallel:
markUsed(c, n.info, s, c.graph.usageSym)
if parallel notin c.features:
localError(c.config, n.info, "use the {.experimental.} pragma to enable 'parallel'")
result = setMs(n, s)
@@ -2163,6 +2175,7 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
result.sons[1] = semStmt(c, x, {})
dec c.inParallelStmt
of mSpawn:
markUsed(c, n.info, s, c.graph.usageSym)
when defined(leanCompiler):
localError(c.config, n.info, "compiler was built without 'spawn' support")
result = n
@@ -2180,10 +2193,12 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
else:
result.add c.graph.emptyNode
of mProcCall:
markUsed(c, n.info, s, c.graph.usageSym)
result = setMs(n, s)
result.sons[1] = semExpr(c, n.sons[1])
result.typ = n[1].typ
of mPlugin:
markUsed(c, n.info, s, c.graph.usageSym)
# semDirectOp with conditional 'afterCallActions':
let nOrig = n.copyTree
#semLazyOpAux(c, n)
@@ -2200,6 +2215,7 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
if callee.magic != mNone:
result = magicsAfterOverloadResolution(c, result, flags)
of mRunnableExamples:
markUsed(c, n.info, s, c.graph.usageSym)
if c.config.cmd == cmdDoc and n.len >= 2 and n.lastSon.kind == nkStmtList:
when false:
# some of this dead code was moved to `prepareExamples`
@@ -2216,8 +2232,9 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
result = setMs(n, s)
else:
result = c.graph.emptyNode
of mSizeOf: result =
semSizeof(c, setMs(n, s))
of mSizeOf:
markUsed(c, n.info, s, c.graph.usageSym)
result = semSizeof(c, setMs(n, s))
else:
result = semDirectOp(c, n, flags)

View File

@@ -535,7 +535,8 @@ proc markOwnerModuleAsUsed(c: PContext; s: PSym) =
if module != nil and module != c.module:
var i = 0
while i <= high(c.unusedImports):
if c.unusedImports[i][0] == module:
let candidate = c.unusedImports[i][0]
if candidate == module or c.exportIndirections.contains(idPairToInt(candidate.id, s.id)):
# mark it as used:
c.unusedImports.del(i)
else:

View File

@@ -0,0 +1,27 @@
discard """
cmd: '''nim c --hint[Processing]:off $file'''
nimout: '''
tunused_imports.nim(11, 10) Warning: BEGIN [User]
tunused_imports.nim(27, 10) Warning: END [User]
tunused_imports.nim(25, 8) Warning: imported and not used: 'strutils' [UnusedImport]
'''
action: "compile"
"""
{.warning: "BEGIN".}
import net
echo AF_UNIX
import macros
# bug #11809
macro bar(): untyped =
template baz() = discard
result = getAst(baz())
bar()
import strutils
{.warning: "END".}