added first version of a nimfind tool for the poor souls that don't have a good nimsuggest integretation

This commit is contained in:
Andreas Rumpf 2018-11-14 16:04:45 +01:00
commit 6e8ed8c6fa
11 changed files with 326 additions and 52 deletions

View file

@ -63,6 +63,9 @@ type
cacheCounters*: Table[string, BiggestInt]
cacheTables*: Table[string, BTree[string, PNode]]
passes*: seq[TPass]
onDefinition*: proc (graph: ModuleGraph; s: PSym; info: TLineInfo) {.nimcall.}
onDefinitionResolveForward*: proc (graph: ModuleGraph; s: PSym; info: TLineInfo) {.nimcall.}
onUsage*: proc (graph: ModuleGraph; s: PSym; info: TLineInfo) {.nimcall.}
TPassContext* = object of RootObj # the pass's context
PPassContext* = ref TPassContext
@ -78,6 +81,32 @@ type
proc hash*(x: FileIndex): Hash {.borrow.}
when defined(nimfind):
template onUse*(info: TLineInfo; s: PSym) =
when compiles(c.c.graph):
if c.c.graph.onUsage != nil: c.c.graph.onUsage(c.c.graph, s, info)
else:
if c.graph.onUsage != nil: c.graph.onUsage(c.graph, s, info)
template onDef*(info: TLineInfo; s: PSym) =
when compiles(c.c.graph):
if c.c.graph.onDefinition != nil: c.c.graph.onDefinition(c.c.graph, s, info)
else:
if c.graph.onDefinition != nil: c.graph.onDefinition(c.graph, s, info)
template onDefResolveForward*(info: TLineInfo; s: PSym) =
when compiles(c.c.graph):
if c.c.graph.onDefinitionResolveForward != nil:
c.c.graph.onDefinitionResolveForward(c.c.graph, s, info)
else:
if c.graph.onDefinitionResolveForward != nil:
c.graph.onDefinitionResolveForward(c.graph, s, info)
else:
template onUse*(info: TLineInfo; s: PSym) = discard
template onDef*(info: TLineInfo; s: PSym) = discard
template onDefResolveForward*(info: TLineInfo; s: PSym) = discard
proc stopCompile*(g: ModuleGraph): bool {.inline.} =
result = g.doStopCompile != nil and g.doStopCompile()

View file

@ -18,7 +18,7 @@ import
evaltempl, patterns, parampatterns, sempass2, linter, semmacrosanity,
lowerings, pluginsupport, plugins/active, rod, lineinfos
from modulegraphs import ModuleGraph, PPassContext
from modulegraphs import ModuleGraph, PPassContext, onUse, onDef, onDefResolveForward
when defined(nimfix):
import nimfix/prettybase
@ -450,7 +450,7 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
pushInfoContext(c.config, nOrig.info, sym.detailedInfo)
markUsed(c.config, n.info, sym, c.graph.usageSym)
styleCheckUse(n.info, sym)
onUse(n.info, sym)
if sym == c.p.owner:
globalError(c.config, n.info, "recursive dependency: '$1'" % sym.name.s)

View file

@ -122,7 +122,7 @@ proc considerAsgnOrSink(c: var TLiftCtx; t: PType; body, x, y: PNode;
if op == nil:
op = liftBody(c.c, t, c.kind, c.info)
markUsed(c.c.config, c.info, op, c.c.graph.usageSym)
styleCheckUse(c.info, op)
onUse(c.info, op)
body.add newAsgnCall(c.c, op, x, y)
result = true
@ -132,7 +132,7 @@ proc considerOverloadedOp(c: var TLiftCtx; t: PType; body, x, y: PNode): bool =
let op = t.destructor
if op != nil:
markUsed(c.c.config, c.info, op, c.c.graph.usageSym)
styleCheckUse(c.info, op)
onUse(c.info, op)
body.add destructorCall(c.c, op, x)
result = true
of attachedAsgn:
@ -143,7 +143,7 @@ proc considerOverloadedOp(c: var TLiftCtx; t: PType; body, x, y: PNode): bool =
let op = t.deepCopy
if op != nil:
markUsed(c.c.config, c.info, op, c.c.graph.usageSym)
styleCheckUse(c.info, op)
onUse(c.info, op)
body.add newDeepCopyCall(op, x, y)
result = true

View file

@ -454,7 +454,7 @@ proc semResolvedCall(c: PContext, x: TCandidate,
assert x.state == csMatch
var finalCallee = x.calleeSym
markUsed(c.config, n.sons[0].info, finalCallee, c.graph.usageSym)
styleCheckUse(n.sons[0].info, finalCallee)
onUse(n.sons[0].info, finalCallee)
assert finalCallee.ast != nil
if x.hasFauxMatch:
result = x.call
@ -562,7 +562,7 @@ proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode =
var newInst = generateInstance(c, s, m.bindings, n.info)
newInst.typ.flags.excl tfUnresolved
markUsed(c.config, n.info, s, c.graph.usageSym)
styleCheckUse(n.info, s)
onUse(n.info, s)
result = newSymNode(newInst, n.info)
proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =

View file

@ -25,7 +25,7 @@ const
proc semTemplateExpr(c: PContext, n: PNode, s: PSym,
flags: TExprFlags = {}): PNode =
markUsed(c.config, n.info, s, c.graph.usageSym)
styleCheckUse(n.info, s)
onUse(n.info, s)
pushInfoContext(c.config, n.info, s.detailedInfo)
result = evalTemplate(n, s, getCurrOwner(c), c.config, efFromHlo in flags)
if efNoSemCheck notin flags: result = semAfterMacroCall(c, n, result, s, flags)
@ -265,7 +265,7 @@ proc semConv(c: PContext, n: PNode): PNode =
let status = checkConvertible(c, result.typ, it.typ)
if status in {convOK, convNotNeedeed}:
markUsed(c.config, n.info, it.sym, c.graph.usageSym)
styleCheckUse(n.info, it.sym)
onUse(n.info, it.sym)
markIndirect(c, it.sym)
return it
errorUseQualifier(c, n.info, op.sons[0].sym)
@ -1036,7 +1036,7 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
case s.kind
of skConst:
markUsed(c.config, n.info, s, c.graph.usageSym)
styleCheckUse(n.info, s)
onUse(n.info, s)
case skipTypes(s.typ, abstractInst-{tyTypeDesc}).kind
of tyNil, tyChar, tyInt..tyInt64, tyFloat..tyFloat128,
tyTuple, tySet, tyUInt..tyUInt64:
@ -1061,7 +1061,7 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
if efNoEvaluateGeneric in flags and s.ast[genericParamsPos].len > 0 or
(n.kind notin nkCallKinds and s.requiredParams > 0):
markUsed(c.config, n.info, s, c.graph.usageSym)
styleCheckUse(n.info, s)
onUse(n.info, s)
result = symChoice(c, n, s, scClosed)
else:
result = semMacroExpr(c, n, n, s, flags)
@ -1070,13 +1070,13 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
(n.kind notin nkCallKinds and s.requiredParams > 0) or
sfCustomPragma in sym.flags:
markUsed(c.config, n.info, s, c.graph.usageSym)
styleCheckUse(n.info, s)
onUse(n.info, s)
result = symChoice(c, n, s, scClosed)
else:
result = semTemplateExpr(c, n, s, flags)
of skParam:
markUsed(c.config, n.info, s, c.graph.usageSym)
styleCheckUse(n.info, s)
onUse(n.info, s)
if s.typ != nil and s.typ.kind == tyStatic and s.typ.n != nil:
# XXX see the hack in sigmatch.nim ...
return s.typ.n
@ -1098,14 +1098,14 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
localError(c.config, n.info, "illegal context for 'nimvm' magic")
markUsed(c.config, n.info, s, c.graph.usageSym)
styleCheckUse(n.info, s)
onUse(n.info, s)
result = newSymNode(s, n.info)
# We cannot check for access to outer vars for example because it's still
# not sure the symbol really ends up being used:
# var len = 0 # but won't be called
# genericThatUsesLen(x) # marked as taking a closure?
of skGenericParam:
styleCheckUse(n.info, s)
onUse(n.info, s)
if s.typ.kind == tyStatic:
result = newSymNode(s, n.info)
result.typ = s.typ
@ -1116,7 +1116,7 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
return n
of skType:
markUsed(c.config, n.info, s, c.graph.usageSym)
styleCheckUse(n.info, s)
onUse(n.info, s)
if s.typ.kind == tyStatic and s.typ.base.kind != tyNone and s.typ.n != nil:
return s.typ.n
result = newSymNode(s, n.info)
@ -1138,7 +1138,7 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
# is the access to a public field or in the same module or in a friend?
doAssert f == s
markUsed(c.config, n.info, f, c.graph.usageSym)
styleCheckUse(n.info, f)
onUse(n.info, f)
result = newNodeIT(nkDotExpr, n.info, f.typ)
result.add makeDeref(newSymNode(p.selfSym))
result.add newSymNode(f) # we now have the correct field
@ -1151,11 +1151,11 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
ty = skipTypes(ty.sons[0], skipPtrs)
# old code, not sure if it's live code:
markUsed(c.config, n.info, s, c.graph.usageSym)
styleCheckUse(n.info, s)
onUse(n.info, s)
result = newSymNode(s, n.info)
else:
markUsed(c.config, n.info, s, c.graph.usageSym)
styleCheckUse(n.info, s)
onUse(n.info, s)
result = newSymNode(s, n.info)
proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
@ -1178,7 +1178,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
else:
markUsed(c.config, n.sons[1].info, s, c.graph.usageSym)
result = semSym(c, n, s, flags)
styleCheckUse(n.sons[1].info, s)
onUse(n.sons[1].info, s)
return
n.sons[0] = semExprWithType(c, n.sons[0], flags+{efDetermineType})
@ -1241,7 +1241,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
result.info = n.info
result.typ = ty
markUsed(c.config, n.info, f, c.graph.usageSym)
styleCheckUse(n.info, f)
onUse(n.info, f)
return
of tyObject, tyTuple:
if ty.n != nil and ty.n.kind == nkRecList:
@ -1272,7 +1272,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
if fieldVisible(c, f):
# is the access to a public field or in the same module or in a friend?
markUsed(c.config, n.sons[1].info, f, c.graph.usageSym)
styleCheckUse(n.sons[1].info, f)
onUse(n.sons[1].info, f)
n.sons[0] = makeDeref(n.sons[0])
n.sons[1] = newSymNode(f) # we now have the correct field
n.typ = f.typ
@ -1286,7 +1286,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
f = getSymFromList(ty.n, i)
if f != nil:
markUsed(c.config, n.sons[1].info, f, c.graph.usageSym)
styleCheckUse(n.sons[1].info, f)
onUse(n.sons[1].info, f)
n.sons[0] = makeDeref(n.sons[0])
n.sons[1] = newSymNode(f)
n.typ = f.typ
@ -1758,7 +1758,7 @@ proc semExpandToAst(c: PContext, n: PNode): PNode =
macroCall.sons[0] = newSymNode(expandedSym, macroCall.info)
markUsed(c.config, n.info, expandedSym, c.graph.usageSym)
styleCheckUse(n.info, expandedSym)
onUse(n.info, expandedSym)
if isCallExpr(macroCall):
for i in countup(1, macroCall.len-1):
@ -1783,7 +1783,7 @@ proc semExpandToAst(c: PContext, n: PNode): PNode =
let info = macroCall.sons[0].info
macroCall.sons[0] = newSymNode(cand, info)
markUsed(c.config, info, cand, c.graph.usageSym)
styleCheckUse(info, cand)
onUse(info, cand)
# we just perform overloading resolution here:
#n.sons[1] = semOverloadedCall(c, macroCall, macroCall, {skTemplate, skMacro})
@ -2265,6 +2265,7 @@ proc semBlock(c: PContext, n: PNode; flags: TExprFlags): PNode =
n.sons[0] = newSymNode(labl, n.sons[0].info)
suggestSym(c.config, n.sons[0].info, labl, c.graph.usageSym)
styleCheckDef(c.config, labl)
onDef(n[0].info, labl)
n.sons[1] = semExpr(c, n.sons[1], flags)
n.typ = n.sons[1].typ
if isEmptyType(n.typ): n.kind = nkBlockStmt

View file

@ -76,14 +76,14 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym,
result = symChoice(c, n, s, scOpen)
of skTemplate:
if macroToExpandSym(s):
styleCheckUse(n.info, s)
onUse(n.info, s)
result = semTemplateExpr(c, n, s, {efNoSemCheck})
result = semGenericStmt(c, result, {}, ctx)
else:
result = symChoice(c, n, s, scOpen)
of skMacro:
if macroToExpandSym(s):
styleCheckUse(n.info, s)
onUse(n.info, s)
result = semMacroExpr(c, n, n, s, {efNoSemCheck})
result = semGenericStmt(c, result, {}, ctx)
else:
@ -96,20 +96,20 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym,
result = n
else:
result = newSymNodeTypeDesc(s, n.info)
styleCheckUse(n.info, s)
onUse(n.info, s)
of skParam:
result = n
styleCheckUse(n.info, s)
onUse(n.info, s)
of skType:
if (s.typ != nil) and
(s.typ.flags * {tfGenericTypeParam, tfImplicitTypeParam} == {}):
result = newSymNodeTypeDesc(s, n.info)
else:
result = n
styleCheckUse(n.info, s)
onUse(n.info, s)
else:
result = newSymNode(s, n.info)
styleCheckUse(n.info, s)
onUse(n.info, s)
proc lookup(c: PContext, n: PNode, flags: TSemGenericFlags,
ctx: var GenericCtx): PNode =
@ -172,6 +172,7 @@ proc addTempDecl(c: PContext; n: PNode; kind: TSymKind) =
let s = newSymS(skUnknown, getIdentNode(c, n), c)
addPrelimDecl(c, s)
styleCheckDef(c.config, n.info, s, kind)
onDef(n.info, s)
proc semGenericStmt(c: PContext, n: PNode,
flags: TSemGenericFlags, ctx: var GenericCtx): PNode =
@ -230,7 +231,7 @@ proc semGenericStmt(c: PContext, n: PNode,
case s.kind
of skMacro:
if macroToExpand(s) and sc.safeLen <= 1:
styleCheckUse(fn.info, s)
onUse(fn.info, s)
result = semMacroExpr(c, n, n, s, {efNoSemCheck})
result = semGenericStmt(c, result, flags, ctx)
else:
@ -239,7 +240,7 @@ proc semGenericStmt(c: PContext, n: PNode,
mixinContext = true
of skTemplate:
if macroToExpand(s) and sc.safeLen <= 1:
styleCheckUse(fn.info, s)
onUse(fn.info, s)
result = semTemplateExpr(c, n, s, {efNoSemCheck})
result = semGenericStmt(c, result, flags, ctx)
else:
@ -262,17 +263,17 @@ proc semGenericStmt(c: PContext, n: PNode,
inc first
of skGenericParam:
result.sons[0] = newSymNodeTypeDesc(s, fn.info)
styleCheckUse(fn.info, s)
onUse(fn.info, s)
first = 1
of skType:
# bad hack for generics:
if (s.typ != nil) and (s.typ.kind != tyGenericParam):
result.sons[0] = newSymNodeTypeDesc(s, fn.info)
styleCheckUse(fn.info, s)
onUse(fn.info, s)
first = 1
else:
result.sons[0] = newSymNode(s, fn.info)
styleCheckUse(fn.info, s)
onUse(fn.info, s)
first = 1
elif fn.kind == nkDotExpr:
result.sons[0] = fuzzyLookup(c, fn, flags, ctx, mixinContext)

View file

@ -65,7 +65,7 @@ proc semBreakOrContinue(c: PContext, n: PNode): PNode =
incl(s.flags, sfUsed)
n.sons[0] = x
suggestSym(c.config, x.info, s, c.graph.usageSym)
styleCheckUse(x.info, s)
onUse(x.info, s)
else:
localError(c.config, n.info, errInvalidControlFlowX % s.name.s)
else:
@ -363,6 +363,7 @@ proc semUsing(c: PContext; n: PNode): PNode =
for j in countup(0, length-3):
let v = semIdentDef(c, a.sons[j], skParam)
styleCheckDef(c.config, v)
onDef(a[j].info, v)
v.typ = typ
strTableIncl(c.signatures, v)
else:
@ -494,6 +495,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
continue
var v = semIdentDef(c, a.sons[j], symkind)
styleCheckDef(c.config, v)
onDef(a[j].info, v)
if sfGenSym notin v.flags and not isDiscardUnderscore(v):
addInterfaceDecl(c, v)
when oKeepVariableNames:
@ -548,6 +550,7 @@ proc semConst(c: PContext, n: PNode): PNode =
checkSonsLen(a, 3, c.config)
var v = semIdentDef(c, a.sons[0], skConst)
styleCheckDef(c.config, v)
onDef(a[0].info, v)
var typ: PType = nil
if a.sons[1].kind != nkEmpty: typ = semTypeNode(c, a.sons[1], nil)
@ -591,6 +594,7 @@ proc symForVar(c: PContext, n: PNode): PSym =
let m = if n.kind == nkPragmaExpr: n.sons[0] else: n
result = newSymG(skForVar, m, c)
styleCheckDef(c.config, result)
onDef(n.info, result)
if n.kind == nkPragmaExpr:
pragma(c, result, n.sons[1], forVarPragmas)
@ -696,7 +700,7 @@ proc handleCaseStmtMacro(c: PContext; n: PNode): PNode =
if r.state == csMatch:
var match = r.calleeSym
markUsed(c.config, n[0].info, match, c.graph.usageSym)
styleCheckUse(n[0].info, match)
onUse(n[0].info, match)
# but pass 'n' to the 'match' macro, not 'n[0]':
r.call.sons[1] = n
@ -880,6 +884,7 @@ proc typeSectionLeftSidePass(c: PContext, n: PNode) =
if typsym.isNil:
s = semIdentDef(c, name[1], skType)
styleCheckDef(c.config, s)
onDef(name[1].info, s)
s.typ = newTypeS(tyObject, c)
s.typ.sym = s
s.flags.incl sfForward
@ -894,6 +899,7 @@ proc typeSectionLeftSidePass(c: PContext, n: PNode) =
else:
s = semIdentDef(c, name, skType)
styleCheckDef(c.config, s)
onDef(name.info, s)
s.typ = newTypeS(tyForward, c)
s.typ.sym = s # process pragmas:
if name.kind == nkPragmaExpr:
@ -1625,6 +1631,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
else:
implicitPragmas(c, s, n, validPragmas)
styleCheckDef(c.config, s)
onDef(n[namePos].info, s)
else:
if n.sons[pragmasPos].kind != nkEmpty:
pragma(c, s, n.sons[pragmasPos], validPragmas)
@ -1638,6 +1645,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
localError(c.config, n.sons[pragmasPos].info, errPragmaOnlyInHeaderOfProcX %
("'" & proto.name.s & "' from " & c.config$proto.info))
styleCheckDef(c.config, s)
onDefResolveForward(n[namePos].info, proto)
if sfForward notin proto.flags and proto.magic == mNone:
wrongRedefinition(c, n.info, proto.name.s, proto.info)
excl(proto.flags, sfForward)

View file

@ -160,7 +160,7 @@ proc onlyReplaceParams(c: var TemplCtx, n: PNode): PNode =
if s.owner == c.owner and s.kind == skParam:
incl(s.flags, sfUsed)
result = newSymNode(s, n.info)
styleCheckUse(n.info, s)
onUse(n.info, s)
else:
for i in 0 ..< n.safeLen:
result.sons[i] = onlyReplaceParams(c, n.sons[i])
@ -208,19 +208,20 @@ proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) =
# So we need only check the *current* scope.
let s = localSearchInScope(c.c, considerQuotedIdent(c.c, ident))
if s != nil and s.owner == c.owner and sfGenSym in s.flags:
styleCheckUse(n.info, s)
onUse(n.info, s)
replaceIdentBySym(c.c, n, newSymNode(s, n.info))
elif not (n.kind == nkSym and sfGenSym in n.sym.flags):
let local = newGenSym(k, ident, c)
addPrelimDecl(c.c, local)
styleCheckDef(c.c.config, n.info, local)
onDef(n.info, local)
replaceIdentBySym(c.c, n, newSymNode(local, n.info))
else:
replaceIdentBySym(c.c, n, ident)
proc semTemplSymbol(c: PContext, n: PNode, s: PSym): PNode =
incl(s.flags, sfUsed)
# we do not call styleCheckUse here, as the identifier is not really
# we do not call onUse here, as the identifier is not really
# resolved here. We will fixup the used identifiers later.
case s.kind
of skUnknown:
@ -245,7 +246,7 @@ proc semRoutineInTemplName(c: var TemplCtx, n: PNode): PNode =
if s.owner == c.owner and (s.kind == skParam or sfGenSym in s.flags):
incl(s.flags, sfUsed)
result = newSymNode(s, n.info)
styleCheckUse(n.info, s)
onUse(n.info, s)
else:
for i in countup(0, safeLen(n) - 1):
result.sons[i] = semRoutineInTemplName(c, n.sons[i])
@ -261,6 +262,7 @@ proc semRoutineInTemplBody(c: var TemplCtx, n: PNode, k: TSymKind): PNode =
s.ast = n
addPrelimDecl(c.c, s)
styleCheckDef(c.c.config, n.info, s)
onDef(n.info, s)
n.sons[namePos] = newSymNode(s, n.sons[namePos].info)
else:
n.sons[namePos] = ident
@ -314,7 +316,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
if s.owner == c.owner and s.kind == skParam:
incl(s.flags, sfUsed)
result = newSymNode(s, n.info)
styleCheckUse(n.info, s)
onUse(n.info, s)
elif contains(c.toBind, s.id):
result = symChoice(c.c, n, s, scClosed)
elif contains(c.toMixin, s.name.id):
@ -324,7 +326,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
# var yz: T
incl(s.flags, sfUsed)
result = newSymNode(s, n.info)
styleCheckUse(n.info, s)
onUse(n.info, s)
else:
result = semTemplSymbol(c.c, n, s)
of nkBind:
@ -382,6 +384,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
let s = newGenSym(skLabel, n.sons[0], c)
addPrelimDecl(c.c, s)
styleCheckDef(c.c.config, s)
onDef(n[0].info, s)
n.sons[0] = newSymNode(s, n.sons[0].info)
n.sons[1] = semTemplBody(c, n.sons[1])
closeScope(c)
@ -505,7 +508,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
if s.owner == c.owner and s.kind == skParam and
n.kind == nkAccQuoted and n.len == 1:
incl(s.flags, sfUsed)
styleCheckUse(n.info, s)
onUse(n.info, s)
return newSymNode(s, n.info)
elif contains(c.toBind, s.id):
return symChoice(c.c, n, s, scClosed)
@ -553,6 +556,7 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
else:
s = semIdentVis(c, skTemplate, n.sons[0], {})
styleCheckDef(c.config, s)
onDef(n[0].info, s)
# check parameter list:
#s.scope = c.currentScope
pushOwner(c, s)
@ -635,7 +639,7 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
# semtypes.addParamOrResult). Within the pattern we have to ensure
# to use the param with the proper type though:
incl(s.flags, sfUsed)
styleCheckUse(n.info, s)
onUse(n.info, s)
let x = c.owner.typ.n.sons[s.position+1].sym
assert x.name == s.name
result = newSymNode(x, n.info)

View file

@ -122,6 +122,7 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
if not isPure: strTableAdd(c.module.tab, e)
addSon(result.n, newSymNode(e))
styleCheckDef(c.config, e)
onDef(e.info, e)
if sfGenSym notin e.flags:
if not isPure: addDecl(c, e)
else: importPureEnumField(c, e)
@ -377,7 +378,7 @@ proc semTypeIdent(c: PContext, n: PNode): PSym =
result = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared})
if result != nil:
markUsed(c.config, n.info, result, c.graph.usageSym)
styleCheckUse(n.info, result)
onUse(n.info, result)
if result.kind == skParam and result.typ.kind == tyTypeDesc:
# This is a typedesc param. is it already bound?
@ -466,6 +467,7 @@ proc semTuple(c: PContext, n: PNode, prev: PType): PType =
addSon(result.n, newSymNode(field))
addSonSkipIntLit(result, typ)
styleCheckDef(c.config, a.sons[j].info, field)
onDef(field.info, field)
if result.n.len == 0: result.n = nil
proc semIdentVis(c: PContext, kind: TSymKind, n: PNode,
@ -688,7 +690,6 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
else: rectype.sym
for i in countup(0, sonsLen(n)-3):
var f = semIdentWithPragma(c, skField, n.sons[i], {sfExported})
styleCheckDef(c.config, n.sons[i].info, f)
suggestSym(c.config, n.sons[i].info, f, c.graph.usageSym)
f.typ = typ
f.position = pos
@ -703,6 +704,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
if a.kind == nkEmpty: addSon(father, newSymNode(f))
else: addSon(a, newSymNode(f))
styleCheckDef(c.config, f)
onDef(f.info, f)
if a.kind != nkEmpty: addSon(father, a)
of nkSym:
# This branch only valid during generic object
@ -988,7 +990,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
of tyGenericParam:
markUsed(c.config, info, paramType.sym, c.graph.usageSym)
styleCheckUse(info, paramType.sym)
onUse(info, paramType.sym)
if tfWildcard in paramType.flags:
paramType.flags.excl tfWildcard
paramType.sym.kind = skType
@ -1110,6 +1112,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
rawAddSon(result, finalType)
addParamOrResult(c, arg, kind)
styleCheckDef(c.config, a.sons[j].info, arg)
onDef(a[j].info, arg)
var r: PType
if n.sons[0].kind != nkEmpty:
@ -1637,7 +1640,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
assignType(prev, t)
result = prev
markUsed(c.config, n.info, n.sym, c.graph.usageSym)
styleCheckUse(n.info, n.sym)
onUse(n.info, n.sym)
else:
if s.kind != skError: localError(c.config, n.info, errTypeExpected)
result = newOrPrevType(tyError, prev, c)

View file

@ -13,7 +13,7 @@
import
intsets, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst,
magicsys, condsyms, idents, lexer, options, parampatterns, strutils, trees,
linter, lineinfos
linter, lineinfos, modulegraphs
when (defined(booting) or defined(nimsuggest)) and not defined(leanCompiler):
import docgen
@ -2149,7 +2149,7 @@ proc paramTypesMatch*(m: var TCandidate, f, a: PType,
else:
# only one valid interpretation found:
markUsed(m.c.config, arg.info, arg.sons[best].sym, m.c.graph.usageSym)
styleCheckUse(arg.info, arg.sons[best].sym)
onUse(arg.info, arg.sons[best].sym)
result = paramTypesMatchAux(m, f, arg.sons[best].typ, arg.sons[best],
argOrig)
when false: