next steps to perfect 'suggest'

This commit is contained in:
Araq
2011-02-22 08:58:12 +01:00
parent fdde4d3a92
commit 310faca724
7 changed files with 106 additions and 41 deletions

View File

@@ -398,8 +398,8 @@ proc UnknownLineInfo*(): TLineInfo =
result.fileIndex = -1
var
filenames: seq[string] = @ []
msgContext: seq[TLineInfo] = @ []
filenames: seq[string] = @[]
msgContext: seq[TLineInfo] = @[]
proc pushInfoContext*(info: TLineInfo) =
msgContext.add(info)
@@ -424,10 +424,10 @@ proc ToFilename*(info: TLineInfo): string =
if info.fileIndex == - 1: result = "???"
else: result = filenames[info.fileIndex]
proc ToLinenumber*(info: TLineInfo): int =
proc ToLinenumber*(info: TLineInfo): int {.inline.} =
result = info.line
proc toColumn*(info: TLineInfo): int =
proc toColumn*(info: TLineInfo): int {.inline.} =
result = info.col
var checkPoints: seq[TLineInfo] = @[]
@@ -453,11 +453,18 @@ proc MsgKindToString*(kind: TMsgKind): string =
proc getMessageStr(msg: TMsgKind, arg: string): string =
result = `%`(msgKindToString(msg), [arg])
proc inCheckpoint*(current: TLineInfo): bool =
type
TCheckPointResult* = enum
cpNone, cpFuzzy, cpExact
proc inCheckpoint*(current: TLineInfo): TCheckPointResult =
for i in countup(0, high(checkPoints)):
if (current.line >= checkPoints[i].line) and
(current.fileIndex == (checkPoints[i].fileIndex)):
return true
if current.fileIndex == checkPoints[i].fileIndex:
if current.line == checkPoints[i].line and
abs(current.col-checkPoints[i].col) < 4:
return cpExact
if current.line >= checkPoints[i].line:
return cpFuzzy
type
TErrorHandling = enum doNothing, doAbort, doRaise

View File

@@ -28,8 +28,10 @@ proc considerAcc(n: PNode): PIdent =
GlobalError(n.info, errIdentifierExpected, renderTree(n))
result = nil
proc isTopLevel(c: PContext): bool =
result = c.tab.tos <= 2
proc isTopLevel(c: PContext): bool {.inline.} =
# if we encountered an error, we treat as top-level so that
# cascading errors are not that strange:
result = c.tab.tos <= 2 or msgs.gErrorCounter > 0
proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym =
result = newSym(kind, considerAcc(n), getCurrOwner())

View File

@@ -641,8 +641,6 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
checkSonsLen(n, 2)
n.sons[0] = semExprWithType(c, n.sons[0], {efAllowType} + flags)
if gCmd == cmdSuggest:
suggestFieldAccess(c, n.sons[0])
var i = considerAcc(n.sons[1])
var ty = n.sons[0].Typ
var f: PSym = nil

View File

@@ -7,11 +7,7 @@
# distribution, for details about the copyright.
#
# This module does the instantiation of generic procs.
proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
info: TLineInfo): PSym
# generates an instantiated proc
# This module implements the instantiation of generic procs.
proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable) =
if (n.kind != nkGenericParams):

View File

@@ -561,11 +561,17 @@ proc IndexTypesMatch*(c: PContext, f, a: PType, arg: PNode): PNode =
initCandidate(m, f)
result = paramTypesMatch(c, m, f, a, arg)
proc argtypeMatches*(c: PContext, f, a: PType): bool =
var m: TCandidate
initCandidate(m, f)
result = paramTypesMatch(c, m, f, a, nil) != nil
proc setSon(father: PNode, at: int, son: PNode) =
if sonsLen(father) <= at: setlen(father.sons, at + 1)
father.sons[at] = son
proc matches*(c: PContext, n: PNode, m: var TCandidate) =
proc matchesAux*(c: PContext, n: PNode, m: var TCandidate,
marker: var TIntSet) =
var f = 1 # iterates over formal parameters
var a = 1 # iterates over the actual given arguments
m.state = csMatch # until proven otherwise
@@ -573,8 +579,6 @@ proc matches*(c: PContext, n: PNode, m: var TCandidate) =
m.call.typ = base(m.callee) # may be nil
var formalLen = sonsLen(m.callee.n)
addSon(m.call, copyTree(n.sons[0]))
var marker: TIntSet
IntSetInit(marker)
var container: PNode = nil # constructed container
var formal: PSym = nil
while a < sonsLen(n):
@@ -656,13 +660,26 @@ proc matches*(c: PContext, n: PNode, m: var TCandidate) =
setSon(m.call, formal.position + 1, arg)
inc(a)
inc(f)
f = 1
proc partialMatch*(c: PContext, n: PNode, m: var TCandidate) =
# for 'suggest' support:
var marker: TIntSet
IntSetInit(marker)
matchesAux(c, n, m, marker)
proc matches*(c: PContext, n: PNode, m: var TCandidate) =
var marker: TIntSet
IntSetInit(marker)
matchesAux(c, n, m, marker)
if m.state == csNoMatch: return
# check that every formal parameter got a value:
var f = 1
while f < sonsLen(m.callee.n):
formal = m.callee.n.sons[f].sym
var formal = m.callee.n.sons[f].sym
if not IntSetContainsOrIncl(marker, formal.position):
if formal.ast == nil:
if formal.typ.kind == tyOpenArray:
container = newNodeI(nkBracket, n.info)
var container = newNodeI(nkBracket, n.info)
addSon(m.call, implicitConv(nkHiddenStdConv, formal.typ,
container, m, c))
else:

View File

@@ -40,17 +40,11 @@ proc suggestField(s: PSym) =
if filterSym(s):
MessageOut(SymToStr(s, isLocal=true))
proc suggestExpr*(c: PContext, n: PNode) =
if not msgs.inCheckpoint(n.info): return
template wholeSymTab(cond: expr) =
for i in countdown(c.tab.tos-1, 0):
for it in items(c.tab.stack[i]):
if filterSym(it):
if cond:
MessageOut(SymToStr(it, isLocal = i > ModuleTablePos))
quit(0)
proc suggestStmt*(c: PContext, n: PNode) =
suggestExpr(c, n)
proc suggestSymList(list: PNode) =
for i in countup(0, sonsLen(list) - 1):
@@ -60,20 +54,45 @@ proc suggestSymList(list: PNode) =
proc suggestObject(n: PNode) =
case n.kind
of nkRecList:
for i in countup(0, sonsLen(n) - 1): suggestObject(n.sons[i])
for i in countup(0, sonsLen(n)-1): suggestObject(n.sons[i])
of nkRecCase:
var L = sonsLen(n)
if L > 0:
suggestObject(n.sons[0])
for i in countup(1, L-1):
suggestObject(lastSon(n.sons[i]))
for i in countup(1, L-1): suggestObject(lastSon(n.sons[i]))
of nkSym: suggestField(n.sym)
else: nil
proc suggestOperations(c: PContext, n: PNode, typ: PType) =
nil
proc nameFits(c: PContext, s: PSym, n: PNode): bool =
result = n.sons[0].kind == nkSym and n.sons[0].sym.name.id == s.name.id
proc suggestFieldAccess*(c: PContext, n: PNode) =
proc argsFit(c: PContext, candidate: PSym, n: PNode): bool =
case candidate.kind
of skProc, skIterator, skMethod:
var m: TCandidate
initCandidate(m, candidate, nil)
sigmatch.partialMatch(c, n, m)
result = m.state != csNoMatch
of skTemplate, skMacro:
result = true
else:
result = false
proc suggestCall*(c: PContext, n: PNode) =
wholeSymTab(filterSym(it) and nameFits(c, it, n) and argsFit(c, it, n))
proc typeFits(c: PContext, s: PSym, firstArg: PType): bool {.inline.} =
if s.typ != nil and sonsLen(s.typ) > 1:
result = sigmatch.argtypeMatches(c, s.typ.sons[1], firstArg)
proc suggestOperations(c: PContext, n: PNode, typ: PType) =
assert typ != nil
wholeSymTab(filterSym(it) and typeFits(c, it, typ))
proc suggestEverything(c: PContext, n: PNode) =
wholeSymTab(filterSym(it))
proc suggestFieldAccess(c: PContext, n: PNode) =
# special code that deals with ``myObj.``. `n` is NOT the nkDotExpr-node, but
# ``myObj``.
var typ = n.Typ
@@ -89,7 +108,7 @@ proc suggestFieldAccess*(c: PContext, n: PNode) =
if filterSym(it): MessageOut(SymToStr(it, isLocal=false))
else:
# fallback:
suggestExpr(c, n)
suggestEverything(c, n)
elif typ.kind == tyEnum:
# look up if the identifier belongs to the enum:
var t = typ
@@ -111,5 +130,32 @@ proc suggestFieldAccess*(c: PContext, n: PNode) =
suggestOperations(c, n, typ)
else:
# fallback:
suggestExpr(c, n)
suggestEverything(c, n)
proc suggestExpr*(c: PContext, n: PNode) =
var cp = msgs.inCheckpoint(n.info)
if cp == cpNone: return
block:
case n.kind
of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand,
nkCallStrLit, nkMacroStmt:
var a = copyNode(n)
for i in 0..sonsLen(n)-1:
# use as many typed arguments as possible:
var x = c.semExpr(c, n.sons[i])
if x.kind == nkEmpty or x.typ == nil: break
addSon(a, x)
suggestCall(c, n)
break
of nkDotExpr:
if cp == cpExact:
var obj = c.semExpr(c, n.sons[0])
suggestFieldAccess(c, obj)
break
else: nil
suggestEverything(c, n)
quit(0)
proc suggestStmt*(c: PContext, n: PNode) =
suggestExpr(c, n)

View File

@@ -1,4 +1,4 @@
- 'suggest' needs tweaking: support for '.'
- 'suggest' needs tweaking: end-token; testing!
- stdout support for doc, pretty
- thread support: threadvar on Windows seems broken;
@@ -16,7 +16,6 @@
High priority (version 0.9.0)
=============================
- fix implicit generic routines
- fix the streams implementation so that it uses methods
- fix overloading resolution