fixes #1285
This commit is contained in:
parent
c41e099118
commit
3c818c89be
10 changed files with 55 additions and 99 deletions
|
|
@ -287,7 +287,7 @@ proc applyRule*(c: PContext, s: PSym, n: PNode): PNode =
|
||||||
# constraint not fullfilled:
|
# constraint not fullfilled:
|
||||||
if not ok: return nil
|
if not ok: return nil
|
||||||
|
|
||||||
markUsed(n, s)
|
markUsed(n.info, s)
|
||||||
if ctx.subMatch:
|
if ctx.subMatch:
|
||||||
assert m.len == 3
|
assert m.len == 3
|
||||||
m.sons[1] = result
|
m.sons[1] = result
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# The Nimrod Compiler
|
# The Nimrod Compiler
|
||||||
# (c) Copyright 2013 Andreas Rumpf
|
# (c) Copyright 2014 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -149,8 +149,8 @@ proc checkDef(c: PGen; n: PNode) =
|
||||||
if n.kind != nkSym: return
|
if n.kind != nkSym: return
|
||||||
checkDef(n, n.sym)
|
checkDef(n, n.sym)
|
||||||
|
|
||||||
proc checkUse*(n: PNode, s: PSym) =
|
proc checkUse*(info: TLineInfo; s: PSym) =
|
||||||
if n.info.fileIndex < 0: return
|
if info.fileIndex < 0: return
|
||||||
# we simply convert it to what it looks like in the definition
|
# we simply convert it to what it looks like in the definition
|
||||||
# for consistency
|
# for consistency
|
||||||
|
|
||||||
|
|
@ -159,10 +159,10 @@ proc checkUse*(n: PNode, s: PSym) =
|
||||||
if s.kind in {skType, skGenericParam} and sfAnon in s.flags: return
|
if s.kind in {skType, skGenericParam} and sfAnon in s.flags: return
|
||||||
let newName = s.name.s
|
let newName = s.name.s
|
||||||
|
|
||||||
loadFile(n.info)
|
loadFile(info)
|
||||||
|
|
||||||
let line = gSourceFiles[n.info.fileIndex].lines[n.info.line-1]
|
let line = gSourceFiles[info.fileIndex].lines[info.line-1]
|
||||||
var first = min(n.info.col.int, line.len)
|
var first = min(info.col.int, line.len)
|
||||||
if first < 0: return
|
if first < 0: return
|
||||||
#inc first, skipIgnoreCase(line, "proc ", first)
|
#inc first, skipIgnoreCase(line, "proc ", first)
|
||||||
while first > 0 and line[first-1] in Letters: dec first
|
while first > 0 and line[first-1] in Letters: dec first
|
||||||
|
|
@ -179,8 +179,8 @@ proc checkUse*(n: PNode, s: PSym) =
|
||||||
if x.match(peg"\s* {\ident} \s* '=' \s* y$1 ('#' .*)?"):
|
if x.match(peg"\s* {\ident} \s* '=' \s* y$1 ('#' .*)?"):
|
||||||
x = ""
|
x = ""
|
||||||
|
|
||||||
system.shallowCopy(gSourceFiles[n.info.fileIndex].lines[n.info.line-1], x)
|
system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x)
|
||||||
gSourceFiles[n.info.fileIndex].dirty = true
|
gSourceFiles[info.fileIndex].dirty = true
|
||||||
|
|
||||||
when false:
|
when false:
|
||||||
var cannotRename = initIntSet()
|
var cannotRename = initIntSet()
|
||||||
|
|
@ -220,53 +220,9 @@ when false:
|
||||||
result.add s[i]
|
result.add s[i]
|
||||||
inc i
|
inc i
|
||||||
|
|
||||||
proc checkUse(c: PGen; n: PNode) =
|
|
||||||
if n.info.fileIndex < 0: return
|
|
||||||
let s = n.sym
|
|
||||||
# operators stay as they are:
|
|
||||||
if s.kind in {skResult, skTemp} or s.name.s[0] notin Letters: return
|
|
||||||
if s.kind in {skType, skGenericParam} and sfAnon in s.flags: return
|
|
||||||
|
|
||||||
if s.id in cannotRename: return
|
|
||||||
|
|
||||||
let newName = if rules.hasKey(s.name.s): rules[s.name.s]
|
|
||||||
else: beautifyName(s.name.s, n.sym.kind)
|
|
||||||
|
|
||||||
loadFile(n.info)
|
|
||||||
|
|
||||||
let line = gSourceFiles[n.info.fileIndex].lines[n.info.line-1]
|
|
||||||
var first = min(n.info.col.int, line.len)
|
|
||||||
if first < 0: return
|
|
||||||
#inc first, skipIgnoreCase(line, "proc ", first)
|
|
||||||
while first > 0 and line[first-1] in Letters: dec first
|
|
||||||
if first < 0: return
|
|
||||||
if line[first] == '`': inc first
|
|
||||||
|
|
||||||
if {sfImportc, sfExportc} * s.flags != {}:
|
|
||||||
# careful, we must ensure the resulting name still matches the external
|
|
||||||
# name:
|
|
||||||
if newName != s.name.s and newName != s.loc.r.ropeToStr and
|
|
||||||
lfFullExternalName notin s.loc.flags:
|
|
||||||
#Message(n.info, errGenerated,
|
|
||||||
# "cannot rename $# to $# due to external name" % [s.name.s, newName])
|
|
||||||
cannotRename.incl(s.id)
|
|
||||||
return
|
|
||||||
let last = first+identLen(line, first)-1
|
|
||||||
if differ(line, first, last, newName):
|
|
||||||
# last-first+1 != newName.len or
|
|
||||||
var x = line.subStr(0, first-1) & newName & line.substr(last+1)
|
|
||||||
when removeTP:
|
|
||||||
# the WinAPI module is full of 'TX = X' which after the substitution
|
|
||||||
# becomes 'X = X'. We remove those lines:
|
|
||||||
if x.match(peg"\s* {\ident} \s* '=' \s* y$1 ('#' .*)?"):
|
|
||||||
x = ""
|
|
||||||
|
|
||||||
system.shallowCopy(gSourceFiles[n.info.fileIndex].lines[n.info.line-1], x)
|
|
||||||
gSourceFiles[n.info.fileIndex].dirty = true
|
|
||||||
|
|
||||||
proc check(c: PGen, n: PNode) =
|
proc check(c: PGen, n: PNode) =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkSym: checkUse(n, n.sym)
|
of nkSym: checkUse(n.info, n.sym)
|
||||||
of nkBlockStmt, nkBlockExpr, nkBlockType:
|
of nkBlockStmt, nkBlockExpr, nkBlockType:
|
||||||
checkDef(c, n[0])
|
checkDef(c, n[0])
|
||||||
check(c, n.sons[1])
|
check(c, n.sons[1])
|
||||||
|
|
|
||||||
|
|
@ -305,7 +305,7 @@ proc semAfterMacroCall(c: PContext, n: PNode, s: PSym,
|
||||||
|
|
||||||
proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
|
proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
|
||||||
flags: TExprFlags = {}): PNode =
|
flags: TExprFlags = {}): PNode =
|
||||||
markUsed(n, sym)
|
markUsed(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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -251,7 +251,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], finalCallee)
|
markUsed(n.sons[0].info, finalCallee)
|
||||||
if finalCallee.ast == nil:
|
if finalCallee.ast == nil:
|
||||||
internalError(n.info, "calleeSym.ast is nil") # XXX: remove this check!
|
internalError(n.info, "calleeSym.ast is nil") # XXX: remove this check!
|
||||||
if finalCallee.ast.sons[genericParamsPos].kind != nkEmpty:
|
if finalCallee.ast.sons[genericParamsPos].kind != nkEmpty:
|
||||||
|
|
@ -283,7 +283,7 @@ proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode =
|
||||||
var m: TCandidate
|
var m: TCandidate
|
||||||
initCandidate(c, m, s, n)
|
initCandidate(c, m, s, n)
|
||||||
var newInst = generateInstance(c, s, m.bindings, n.info)
|
var newInst = generateInstance(c, s, m.bindings, n.info)
|
||||||
markUsed(n, s)
|
markUsed(n.info, s)
|
||||||
result = newSymNode(newInst, n.info)
|
result = newSymNode(newInst, n.info)
|
||||||
|
|
||||||
proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
|
proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
proc semTemplateExpr(c: PContext, n: PNode, s: PSym,
|
proc semTemplateExpr(c: PContext, n: PNode, s: PSym,
|
||||||
flags: TExprFlags = {}): PNode =
|
flags: TExprFlags = {}): PNode =
|
||||||
markUsed(n, s)
|
markUsed(n.info, s)
|
||||||
pushInfoContext(n.info)
|
pushInfoContext(n.info)
|
||||||
result = evalTemplate(n, s, getCurrOwner())
|
result = evalTemplate(n, s, getCurrOwner())
|
||||||
if efNoSemCheck notin flags: result = semAfterMacroCall(c, result, s, flags)
|
if efNoSemCheck notin flags: result = semAfterMacroCall(c, result, s, flags)
|
||||||
|
|
@ -78,7 +78,7 @@ proc inlineConst(n: PNode, s: PSym): PNode {.inline.} =
|
||||||
proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
|
proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
|
||||||
case s.kind
|
case s.kind
|
||||||
of skConst:
|
of skConst:
|
||||||
markUsed(n, s)
|
markUsed(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,
|
||||||
tyTuple, tySet, tyUInt..tyUInt64:
|
tyTuple, tySet, tyUInt..tyUInt64:
|
||||||
|
|
@ -101,7 +101,7 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
|
||||||
of skMacro: result = semMacroExpr(c, n, n, s, flags)
|
of skMacro: result = semMacroExpr(c, n, n, s, flags)
|
||||||
of skTemplate: result = semTemplateExpr(c, n, s, flags)
|
of skTemplate: result = semTemplateExpr(c, n, s, flags)
|
||||||
of skVar, skLet, skResult, skParam, skForVar:
|
of skVar, skLet, skResult, skParam, skForVar:
|
||||||
markUsed(n, s)
|
markUsed(n.info, s)
|
||||||
# if a proc accesses a global variable, it is not side effect free:
|
# if a proc accesses a global variable, it is not side effect free:
|
||||||
if sfGlobal in s.flags:
|
if sfGlobal in s.flags:
|
||||||
incl(c.p.owner.flags, sfSideEffect)
|
incl(c.p.owner.flags, sfSideEffect)
|
||||||
|
|
@ -123,13 +123,13 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
|
||||||
n.typ = s.typ
|
n.typ = s.typ
|
||||||
return n
|
return n
|
||||||
of skType:
|
of skType:
|
||||||
markUsed(n, s)
|
markUsed(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
|
||||||
result = newSymNode(s, n.info)
|
result = newSymNode(s, n.info)
|
||||||
result.typ = makeTypeDesc(c, s.typ)
|
result.typ = makeTypeDesc(c, s.typ)
|
||||||
else:
|
else:
|
||||||
markUsed(n, s)
|
markUsed(n.info, s)
|
||||||
result = newSymNode(s, n.info)
|
result = newSymNode(s, n.info)
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -253,7 +253,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, it.sym)
|
markUsed(n.info, it.sym)
|
||||||
markIndirect(c, it.sym)
|
markIndirect(c, it.sym)
|
||||||
return it
|
return it
|
||||||
localError(n.info, errUseQualifier, op.sons[0].sym.name.s)
|
localError(n.info, errUseQualifier, op.sons[0].sym.name.s)
|
||||||
|
|
@ -971,7 +971,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
|
|
||||||
var s = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared})
|
var s = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared})
|
||||||
if s != nil:
|
if s != nil:
|
||||||
markUsed(n.sons[1], s)
|
markUsed(n.sons[1].info, s)
|
||||||
return semSym(c, n, s, flags)
|
return semSym(c, n, s, flags)
|
||||||
|
|
||||||
n.sons[0] = semExprWithType(c, n.sons[0], flags+{efDetermineType})
|
n.sons[0] = semExprWithType(c, n.sons[0], flags+{efDetermineType})
|
||||||
|
|
@ -994,7 +994,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, f)
|
markUsed(n.info, f)
|
||||||
return
|
return
|
||||||
of tyTypeParamsHolders:
|
of tyTypeParamsHolders:
|
||||||
return readTypeParameter(c, ty, i, n.info)
|
return readTypeParameter(c, ty, i, n.info)
|
||||||
|
|
@ -1026,7 +1026,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], f)
|
markUsed(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
|
||||||
n.typ = f.typ
|
n.typ = f.typ
|
||||||
|
|
@ -1039,7 +1039,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], f)
|
markUsed(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)
|
||||||
n.typ = f.typ
|
n.typ = f.typ
|
||||||
|
|
@ -1450,7 +1450,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, expandedSym)
|
markUsed(n.info, expandedSym)
|
||||||
|
|
||||||
for i in countup(1, macroCall.len-1):
|
for i in countup(1, macroCall.len-1):
|
||||||
macroCall.sons[i] = semExprWithType(c, macroCall[i], {})
|
macroCall.sons[i] = semExprWithType(c, macroCall[i], {})
|
||||||
|
|
@ -1881,7 +1881,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], labl)
|
suggestSym(n.sons[0].info, 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
|
||||||
if isEmptyType(n.typ): n.kind = nkBlockStmt
|
if isEmptyType(n.typ): n.kind = nkBlockStmt
|
||||||
|
|
@ -2001,7 +2001,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
var s = qualifiedLookUp(c, n.sons[0], mode)
|
var s = qualifiedLookUp(c, n.sons[0], mode)
|
||||||
if s != nil:
|
if s != nil:
|
||||||
if gCmd == cmdPretty and n.sons[0].kind == nkDotExpr:
|
if gCmd == cmdPretty and n.sons[0].kind == nkDotExpr:
|
||||||
pretty.checkUse(n.sons[0].sons[1], s)
|
pretty.checkUse(n.sons[0].sons[1].info, s)
|
||||||
case s.kind
|
case s.kind
|
||||||
of skMacro:
|
of skMacro:
|
||||||
if sfImmediate notin s.flags:
|
if sfImmediate notin s.flags:
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,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, s)
|
suggestSym(x.info, s)
|
||||||
else:
|
else:
|
||||||
localError(n.info, errInvalidControlFlowX, s.name.s)
|
localError(n.info, errInvalidControlFlowX, s.name.s)
|
||||||
elif (c.p.nestedLoopCounter <= 0) and (c.p.nestedBlockCounter <= 0):
|
elif (c.p.nestedLoopCounter <= 0) and (c.p.nestedBlockCounter <= 0):
|
||||||
|
|
@ -319,7 +319,7 @@ proc semIdentDef(c: PContext, n: PNode, kind: TSymKind): PSym =
|
||||||
incl(result.flags, sfGlobal)
|
incl(result.flags, sfGlobal)
|
||||||
else:
|
else:
|
||||||
result = semIdentWithPragma(c, kind, n, {})
|
result = semIdentWithPragma(c, kind, n, {})
|
||||||
suggestSym(n, result)
|
suggestSym(n.info, result)
|
||||||
|
|
||||||
proc checkNilable(v: PSym) =
|
proc checkNilable(v: PSym) =
|
||||||
if sfGlobal in v.flags and {tfNotNil, tfNeedsInit} * v.typ.flags != {}:
|
if sfGlobal in v.flags and {tfNotNil, tfNeedsInit} * v.typ.flags != {}:
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,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, s)
|
markUsed(n.info, s)
|
||||||
else:
|
else:
|
||||||
# semantic checking requires a type; ``fitNode`` deals with it
|
# semantic checking requires a type; ``fitNode`` deals with it
|
||||||
# appropriately
|
# appropriately
|
||||||
|
|
|
||||||
|
|
@ -281,7 +281,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, result)
|
markUsed(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?
|
||||||
# it's not bound when it's used multiple times in the
|
# it's not bound when it's used multiple times in the
|
||||||
|
|
@ -562,7 +562,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var TIntSet, 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], f)
|
suggestSym(n.sons[i].info, f)
|
||||||
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
|
||||||
|
|
@ -827,7 +827,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||||
result = addImplicitGeneric(newTypeS(tyAnything, c))
|
result = addImplicitGeneric(newTypeS(tyAnything, c))
|
||||||
|
|
||||||
of tyGenericParam:
|
of tyGenericParam:
|
||||||
markUsed(genericParams, paramType.sym)
|
markUsed(info, paramType.sym)
|
||||||
if tfWildcard in paramType.flags:
|
if tfWildcard in paramType.flags:
|
||||||
paramType.flags.excl tfWildcard
|
paramType.flags.excl tfWildcard
|
||||||
paramType.sym.kind = skType
|
paramType.sym.kind = skType
|
||||||
|
|
@ -1181,7 +1181,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
else:
|
else:
|
||||||
assignType(prev, t)
|
assignType(prev, t)
|
||||||
result = prev
|
result = prev
|
||||||
markUsed(n, n.sym)
|
markUsed(n.info, n.sym)
|
||||||
else:
|
else:
|
||||||
if n.sym.kind != skError: localError(n.info, errTypeExpected)
|
if n.sym.kind != skError: localError(n.info, errTypeExpected)
|
||||||
result = newOrPrevType(tyError, prev, c)
|
result = newOrPrevType(tyError, prev, c)
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ type
|
||||||
const
|
const
|
||||||
isNilConversion = isConvertible # maybe 'isIntConv' fits better?
|
isNilConversion = isConvertible # maybe 'isIntConv' fits better?
|
||||||
|
|
||||||
proc markUsed*(n: PNode, s: PSym)
|
proc markUsed*(info: TLineInfo, s: PSym)
|
||||||
|
|
||||||
proc initCandidateAux(ctx: PContext,
|
proc initCandidateAux(ctx: PContext,
|
||||||
c: var TCandidate, callee: PType) {.inline.} =
|
c: var TCandidate, callee: PType) {.inline.} =
|
||||||
|
|
@ -1058,7 +1058,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, c.converters[i])
|
markUsed(arg.info, c.converters[i])
|
||||||
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
|
||||||
|
|
@ -1271,7 +1271,7 @@ proc paramTypesMatch*(m: var TCandidate, f, a: PType,
|
||||||
result = nil
|
result = nil
|
||||||
else:
|
else:
|
||||||
# only one valid interpretation found:
|
# only one valid interpretation found:
|
||||||
markUsed(arg, arg.sons[best].sym)
|
markUsed(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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -246,18 +246,18 @@ var
|
||||||
usageSym*: PSym
|
usageSym*: PSym
|
||||||
lastLineInfo: TLineInfo
|
lastLineInfo: TLineInfo
|
||||||
|
|
||||||
proc findUsages(node: PNode, s: PSym) =
|
proc findUsages(info: TLineInfo; s: PSym) =
|
||||||
if usageSym == nil and isTracked(node.info, s.name.s.len):
|
if usageSym == nil and isTracked(info, s.name.s.len):
|
||||||
usageSym = s
|
usageSym = s
|
||||||
suggestWriteln(symToStr(s, isLocal=false, sectionUsage))
|
suggestWriteln(symToStr(s, isLocal=false, sectionUsage))
|
||||||
elif s == usageSym:
|
elif s == usageSym:
|
||||||
if lastLineInfo != node.info:
|
if lastLineInfo != info:
|
||||||
suggestWriteln(symToStr(s, isLocal=false, sectionUsage, node.info))
|
suggestWriteln(symToStr(s, isLocal=false, sectionUsage, info))
|
||||||
lastLineInfo = node.info
|
lastLineInfo = info
|
||||||
|
|
||||||
proc findDefinition(node: PNode, s: PSym) =
|
proc findDefinition(info: TLineInfo; s: PSym) =
|
||||||
if node.isNil or s.isNil: return
|
if s.isNil: return
|
||||||
if isTracked(node.info, s.name.s.len):
|
if isTracked(info, s.name.s.len):
|
||||||
suggestWriteln(symToStr(s, isLocal=false, sectionDef))
|
suggestWriteln(symToStr(s, isLocal=false, sectionDef))
|
||||||
suggestQuit()
|
suggestQuit()
|
||||||
|
|
||||||
|
|
@ -316,26 +316,26 @@ proc defFromSourceMap*(i: TLineInfo) =
|
||||||
|
|
||||||
defFromLine(gSourceMaps[i.fileIndex].lines[i.line].entries, i.col)
|
defFromLine(gSourceMaps[i.fileIndex].lines[i.line].entries, i.col)
|
||||||
|
|
||||||
proc suggestSym*(n: PNode, s: PSym) {.inline.} =
|
proc suggestSym*(info: TLineInfo; s: PSym) {.inline.} =
|
||||||
## misnamed: should be 'symDeclared'
|
## misnamed: should be 'symDeclared'
|
||||||
if optUsages in gGlobalOptions:
|
if optUsages in gGlobalOptions:
|
||||||
findUsages(n, s)
|
findUsages(info, s)
|
||||||
if optDef in gGlobalOptions:
|
if optDef in gGlobalOptions:
|
||||||
findDefinition(n, s)
|
findDefinition(info, s)
|
||||||
if isServing and not n.isNil:
|
if isServing:
|
||||||
addToSourceMap(s, n.info)
|
addToSourceMap(s, info)
|
||||||
|
|
||||||
proc markUsed(n: PNode, s: PSym) =
|
proc markUsed(info: TLineInfo; s: PSym) =
|
||||||
incl(s.flags, sfUsed)
|
incl(s.flags, sfUsed)
|
||||||
if {sfDeprecated, sfError} * s.flags != {}:
|
if {sfDeprecated, sfError} * s.flags != {}:
|
||||||
if sfDeprecated in s.flags: message(n.info, warnDeprecated, s.name.s)
|
if sfDeprecated in s.flags: message(info, warnDeprecated, s.name.s)
|
||||||
if sfError in s.flags: localError(n.info, errWrongSymbolX, s.name.s)
|
if sfError in s.flags: localError(info, errWrongSymbolX, s.name.s)
|
||||||
suggestSym(n, s)
|
suggestSym(info, s)
|
||||||
if gCmd == cmdPretty: checkUse(n, s)
|
if gCmd == cmdPretty: checkUse(info, s)
|
||||||
|
|
||||||
proc useSym*(sym: PSym): PNode =
|
proc useSym*(sym: PSym): PNode =
|
||||||
result = newSymNode(sym)
|
result = newSymNode(sym)
|
||||||
markUsed(result, sym)
|
markUsed(result.info, sym)
|
||||||
|
|
||||||
proc suggestExpr*(c: PContext, node: PNode) =
|
proc suggestExpr*(c: PContext, node: PNode) =
|
||||||
var cp = msgs.inCheckpoint(node.info)
|
var cp = msgs.inCheckpoint(node.info)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue