diff options
Diffstat (limited to 'rod/suggest.nim')
-rw-r--r-- | rod/suggest.nim | 74 |
1 files changed, 67 insertions, 7 deletions
diff --git a/rod/suggest.nim b/rod/suggest.nim index 377c988bd..5eaa2bd9e 100644 --- a/rod/suggest.nim +++ b/rod/suggest.nim @@ -9,7 +9,7 @@ ## This file implements features required for IDE support. -import scanner, ast, astalgo, semdata, msgs, types +import scanner, ast, astalgo, semdata, msgs, types, sigmatch const sep = '\t' @@ -33,23 +33,83 @@ proc SymToStr(s: PSym, isLocal: bool): string = result.add(sep) result.add($ToColumn(s.info)) -proc suggestSym(s: PSym): bool {.inline.} = +proc filterSym(s: PSym): bool {.inline.} = result = s.name.s[0] in scanner.SymChars +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 for i in countdown(c.tab.tos-1, 0): for it in items(c.tab.stack[i]): - if suggestSym(it): - MessageOut(SymToStr(it, i > ModuleTablePos)) + if filterSym(it): + MessageOut(SymToStr(it, isLocal = i > ModuleTablePos)) quit(0) proc suggestStmt*(c: PContext, n: PNode) = - suggestExpr(c, n) + suggestExpr(c, n) + +proc suggestSymList(list: PNode) = + for i in countup(0, sonsLen(list) - 1): + if list.sons[i].kind != nkSym: InternalError(list.info, "getSymFromList") + suggestField(list.sons[i].sym) + +proc suggestObject(n: PNode) = + case n.kind + of nkRecList: + 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])) + of nkSym: suggestField(n.sym) + else: nil +proc suggestOperations(c: PContext, n: PNode, typ: PType) = + nil proc suggestFieldAccess*(c: PContext, n: PNode) = - suggestExpr(c, n) - # XXX provide a better implementation based on n[0].typ + # special code that deals with ``myObj.``. `n` is NOT the nkDotExpr-node, but + # ``myObj``. + var typ = n.Typ + if typ == nil: + # a module symbol has no type for example: + if n.kind == nkSym and n.sym.kind == skModule: + if n.sym == c.module: + # all symbols accessible, because we are in the current module: + for it in items(c.tab.stack[ModuleTablePos]): + if filterSym(it): MessageOut(SymToStr(it, isLocal=false)) + else: + for it in items(n.sym.tab): + if filterSym(it): MessageOut(SymToStr(it, isLocal=false)) + else: + # fallback: + suggestExpr(c, n) + elif typ.kind == tyEnum: + # look up if the identifier belongs to the enum: + var t = typ + while t != nil: + suggestSymList(t.n) + t = t.sons[0] + suggestOperations(c, n, typ) + else: + typ = skipTypes(typ, {tyGenericInst, tyVar, tyPtr, tyRef}) + if typ.kind == tyObject: + var t = typ + while true: + suggestObject(t.n) + if t.sons[0] == nil: break + t = skipTypes(t.sons[0], {tyGenericInst}) + suggestOperations(c, n, typ) + elif typ.kind == tyTuple and typ.n != nil: + suggestSymList(typ.n) + suggestOperations(c, n, typ) + else: + # fallback: + suggestExpr(c, n) |