compiler/sem*: improve lineinfo for qualified and generic procs (#10427)
Previously the compiler will believe these are where `newSeq` symbol
starts:
newSeq[int]()
^
system.newSeq[int]()
^
This commit moves them back to:
newSeq[int]()
^
system.newSeq[int]()
^
This commit is contained in:
parent
f1a841c605
commit
e962be8981
5 changed files with 56 additions and 19 deletions
|
|
@ -462,16 +462,23 @@ proc updateDefaultParams(call: PNode) =
|
||||||
if nfDefaultRefsParam in def.flags: call.flags.incl nfDefaultRefsParam
|
if nfDefaultRefsParam in def.flags: call.flags.incl nfDefaultRefsParam
|
||||||
call[i] = def
|
call[i] = def
|
||||||
|
|
||||||
|
proc getCallLineInfo(n: PNode): TLineInfo =
|
||||||
|
case n.kind
|
||||||
|
of nkBracketExpr, nkCall, nkCommand: getCallLineInfo(n.sons[0])
|
||||||
|
of nkDotExpr: getCallLineInfo(n.sons[1])
|
||||||
|
else: n.info
|
||||||
|
|
||||||
proc semResolvedCall(c: PContext, x: TCandidate,
|
proc semResolvedCall(c: PContext, x: TCandidate,
|
||||||
n: PNode, flags: TExprFlags): PNode =
|
n: PNode, flags: TExprFlags): PNode =
|
||||||
assert x.state == csMatch
|
assert x.state == csMatch
|
||||||
var finalCallee = x.calleeSym
|
var finalCallee = x.calleeSym
|
||||||
markUsed(c.config, n.sons[0].info, finalCallee, c.graph.usageSym)
|
let info = getCallLineInfo(n)
|
||||||
onUse(n.sons[0].info, finalCallee)
|
markUsed(c.config, info, finalCallee, c.graph.usageSym)
|
||||||
|
onUse(info, finalCallee)
|
||||||
assert finalCallee.ast != nil
|
assert finalCallee.ast != nil
|
||||||
if x.hasFauxMatch:
|
if x.hasFauxMatch:
|
||||||
result = x.call
|
result = x.call
|
||||||
result.sons[0] = newSymNode(finalCallee, result.sons[0].info)
|
result.sons[0] = newSymNode(finalCallee, getCallLineInfo(result.sons[0]))
|
||||||
if containsGenericType(result.typ) or x.fauxMatch == tyUnknown:
|
if containsGenericType(result.typ) or x.fauxMatch == tyUnknown:
|
||||||
result.typ = newTypeS(x.fauxMatch, c)
|
result.typ = newTypeS(x.fauxMatch, c)
|
||||||
return
|
return
|
||||||
|
|
@ -496,7 +503,7 @@ proc semResolvedCall(c: PContext, x: TCandidate,
|
||||||
|
|
||||||
result = x.call
|
result = x.call
|
||||||
instGenericConvertersSons(c, result, x)
|
instGenericConvertersSons(c, result, x)
|
||||||
result[0] = newSymNode(finalCallee, result[0].info)
|
result[0] = newSymNode(finalCallee, getCallLineInfo(result[0]))
|
||||||
result.typ = finalCallee.typ.sons[0]
|
result.typ = finalCallee.typ.sons[0]
|
||||||
updateDefaultParams(result)
|
updateDefaultParams(result)
|
||||||
|
|
||||||
|
|
@ -551,7 +558,7 @@ proc semOverloadedCall(c: PContext, n, nOrig: PNode,
|
||||||
notFoundError(c, n, errors)
|
notFoundError(c, n, errors)
|
||||||
|
|
||||||
proc explicitGenericInstError(c: PContext; n: PNode): PNode =
|
proc explicitGenericInstError(c: PContext; n: PNode): PNode =
|
||||||
localError(c.config, n.info, errCannotInstantiateX % renderTree(n))
|
localError(c.config, getCallLineInfo(n), errCannotInstantiateX % renderTree(n))
|
||||||
result = n
|
result = n
|
||||||
|
|
||||||
proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode =
|
proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode =
|
||||||
|
|
@ -574,9 +581,10 @@ proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode =
|
||||||
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)
|
||||||
newInst.typ.flags.excl tfUnresolved
|
newInst.typ.flags.excl tfUnresolved
|
||||||
markUsed(c.config, n.info, s, c.graph.usageSym)
|
let info = getCallLineInfo(n)
|
||||||
onUse(n.info, s)
|
markUsed(c.config, info, s, c.graph.usageSym)
|
||||||
result = newSymNode(newInst, n.info)
|
onUse(info, s)
|
||||||
|
result = newSymNode(newInst, info)
|
||||||
|
|
||||||
proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
|
proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
|
||||||
assert n.kind == nkBracketExpr
|
assert n.kind == nkBracketExpr
|
||||||
|
|
@ -593,7 +601,7 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
|
||||||
# number of generic type parameters:
|
# number of generic type parameters:
|
||||||
if safeLen(s.ast.sons[genericParamsPos]) != n.len-1:
|
if safeLen(s.ast.sons[genericParamsPos]) != n.len-1:
|
||||||
let expected = safeLen(s.ast.sons[genericParamsPos])
|
let expected = safeLen(s.ast.sons[genericParamsPos])
|
||||||
localError(c.config, n.info, errGenerated, "cannot instantiate: '" & renderTree(n) &
|
localError(c.config, getCallLineInfo(n), errGenerated, "cannot instantiate: '" & renderTree(n) &
|
||||||
"'; got " & $(n.len-1) & " type(s) but expected " & $expected)
|
"'; got " & $(n.len-1) & " type(s) but expected " & $expected)
|
||||||
return n
|
return n
|
||||||
result = explicitGenericSym(c, n, s)
|
result = explicitGenericSym(c, n, s)
|
||||||
|
|
@ -602,7 +610,7 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
|
||||||
# choose the generic proc with the proper number of type parameters.
|
# choose the generic proc with the proper number of type parameters.
|
||||||
# XXX I think this could be improved by reusing sigmatch.paramTypesMatch.
|
# XXX I think this could be improved by reusing sigmatch.paramTypesMatch.
|
||||||
# It's good enough for now.
|
# It's good enough for now.
|
||||||
result = newNodeI(a.kind, n.info)
|
result = newNodeI(a.kind, getCallLineInfo(n))
|
||||||
for i in countup(0, len(a)-1):
|
for i in countup(0, len(a)-1):
|
||||||
var candidate = a.sons[i].sym
|
var candidate = a.sons[i].sym
|
||||||
if candidate.kind in {skProc, skMethod, skConverter,
|
if candidate.kind in {skProc, skMethod, skConverter,
|
||||||
|
|
|
||||||
|
|
@ -1171,9 +1171,10 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
|
||||||
onUse(n.info, s)
|
onUse(n.info, s)
|
||||||
result = newSymNode(s, n.info)
|
result = newSymNode(s, n.info)
|
||||||
else:
|
else:
|
||||||
markUsed(c.config, n.info, s, c.graph.usageSym)
|
let info = getCallLineInfo(n)
|
||||||
onUse(n.info, s)
|
markUsed(c.config, info, s, c.graph.usageSym)
|
||||||
result = newSymNode(s, n.info)
|
onUse(info, s)
|
||||||
|
result = newSymNode(s, info)
|
||||||
|
|
||||||
proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
## returns nil if it's not a built-in field access
|
## returns nil if it's not a built-in field access
|
||||||
|
|
|
||||||
|
|
@ -58,25 +58,26 @@ proc symChoice(c: PContext, n: PNode, s: PSym, r: TSymChoiceRule): PNode =
|
||||||
inc(i)
|
inc(i)
|
||||||
if i > 1: break
|
if i > 1: break
|
||||||
a = nextOverloadIter(o, c, n)
|
a = nextOverloadIter(o, c, n)
|
||||||
|
let info = getCallLineInfo(n)
|
||||||
if i <= 1 and r != scForceOpen:
|
if i <= 1 and r != scForceOpen:
|
||||||
# XXX this makes more sense but breaks bootstrapping for now:
|
# XXX this makes more sense but breaks bootstrapping for now:
|
||||||
# (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, info)
|
||||||
markUsed(c.config, n.info, s, c.graph.usageSym)
|
markUsed(c.config, info, s, c.graph.usageSym)
|
||||||
onUse(n.info, s)
|
onUse(info, s)
|
||||||
else:
|
else:
|
||||||
# semantic checking requires a type; ``fitNode`` deals with it
|
# semantic checking requires a type; ``fitNode`` deals with it
|
||||||
# appropriately
|
# appropriately
|
||||||
let kind = if r == scClosed or n.kind == nkDotExpr: nkClosedSymChoice
|
let kind = if r == scClosed or n.kind == nkDotExpr: nkClosedSymChoice
|
||||||
else: nkOpenSymChoice
|
else: nkOpenSymChoice
|
||||||
result = newNodeIT(kind, n.info, newTypeS(tyNone, c))
|
result = newNodeIT(kind, info, newTypeS(tyNone, c))
|
||||||
a = initOverloadIter(o, c, n)
|
a = initOverloadIter(o, c, n)
|
||||||
while a != nil:
|
while a != nil:
|
||||||
if a.kind != skModule:
|
if a.kind != skModule:
|
||||||
incl(a.flags, sfUsed)
|
incl(a.flags, sfUsed)
|
||||||
addSon(result, newSymNode(a, n.info))
|
addSon(result, newSymNode(a, info))
|
||||||
onUse(n.info, a)
|
onUse(info, a)
|
||||||
a = nextOverloadIter(o, c, n)
|
a = nextOverloadIter(o, c, n)
|
||||||
|
|
||||||
proc semBindStmt(c: PContext, n: PNode, toBind: var IntSet): PNode =
|
proc semBindStmt(c: PContext, n: PNode, toBind: var IntSet): PNode =
|
||||||
|
|
|
||||||
18
nimsuggest/tests/tgeneric_highlight.nim
Normal file
18
nimsuggest/tests/tgeneric_highlight.nim
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
newSeq[int]()
|
||||||
|
system.newSeq[int]()#[!]#
|
||||||
|
|
||||||
|
discard """
|
||||||
|
disabled:true
|
||||||
|
$nimsuggest --tester $file
|
||||||
|
>highlight $1
|
||||||
|
highlight;;skType;;1;;7;;3
|
||||||
|
highlight;;skProc;;1;;0;;6
|
||||||
|
highlight;;skProc;;1;;0;;6
|
||||||
|
highlight;;skType;;1;;7;;3
|
||||||
|
highlight;;skProc;;1;;0;;6
|
||||||
|
highlight;;skType;;2;;14;;3
|
||||||
|
highlight;;skProc;;2;;7;;6
|
||||||
|
highlight;;skProc;;2;;7;;6
|
||||||
|
highlight;;skType;;2;;14;;3
|
||||||
|
highlight;;skProc;;2;;7;;6
|
||||||
|
"""
|
||||||
9
nimsuggest/tests/tqualified_highlight.nim
Normal file
9
nimsuggest/tests/tqualified_highlight.nim
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
system.echo#[!]#
|
||||||
|
|
||||||
|
discard """
|
||||||
|
disabled:true
|
||||||
|
$nimsuggest --tester $file
|
||||||
|
>highlight $1
|
||||||
|
highlight;;skProc;;1;;7;;4
|
||||||
|
highlight;;skProc;;1;;7;;4
|
||||||
|
"""
|
||||||
Loading…
Add table
Add a link
Reference in a new issue