diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2017-03-08 00:38:48 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2017-03-08 00:38:48 +0100 |
commit | 91a4b448fdfb1a28e5bd1f1d5785e0308fedcb1a (patch) | |
tree | 9d34b447df1bf08f7207a82c5f4fdc65a619c006 | |
parent | 538c6c98985399314a845617e566313b70ac71e4 (diff) | |
download | Nim-91a4b448fdfb1a28e5bd1f1d5785e0308fedcb1a.tar.gz |
nimsuggest: chk checks the full project lazily; much better suggestions orderings
-rw-r--r-- | compiler/prefixmatches.nim | 4 | ||||
-rw-r--r-- | compiler/suggest.nim | 141 | ||||
-rw-r--r-- | tools/nimsuggest/nimsuggest.nim | 33 | ||||
-rw-r--r-- | tools/nimsuggest/tester.nim | 8 | ||||
-rw-r--r-- | tools/nimsuggest/tests/tno_deref.nim | 2 | ||||
-rw-r--r-- | tools/nimsuggest/tests/tsug_regression.nim | 28 | ||||
-rw-r--r-- | tools/nimsuggest/tests/twithin_macro.nim | 12 | ||||
-rw-r--r-- | tools/nimsuggest/tests/twithin_macro_prefix.nim | 4 |
8 files changed, 164 insertions, 68 deletions
diff --git a/compiler/prefixmatches.nim b/compiler/prefixmatches.nim index 2630225de..9805fdbd2 100644 --- a/compiler/prefixmatches.nim +++ b/compiler/prefixmatches.nim @@ -12,9 +12,9 @@ from strutils import toLowerAscii type PrefixMatch* {.pure.} = enum None, ## no prefix detected - Prefix, ## prefix does match the symbol - Substr, ## prefix is a substring of the symbol Abbrev ## prefix is an abbreviation of the symbol + Substr, ## prefix is a substring of the symbol + Prefix, ## prefix does match the symbol proc prefixMatch*(p, s: string): PrefixMatch = template eq(a, b): bool = a.toLowerAscii == b.toLowerAscii diff --git a/compiler/suggest.nim b/compiler/suggest.nim index 56210d6db..ebabed465 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -32,7 +32,7 @@ # included from sigmatch.nim -import algorithm, sequtils, prefixmatches +import algorithm, prefixmatches when defined(nimsuggest): import passes, tables # importer @@ -41,9 +41,11 @@ const sep = '\t' type - Suggest* = object + Suggest* = ref object section*: IdeCmd qualifiedPath*: seq[string] + name*: PIdent # not used beyond sorting purposes; name is also + # part of 'qualifiedPath' filePath*: string line*: int # Starts at 1 column*: int # Starts at 0 @@ -54,8 +56,9 @@ type isGlobal*: bool # is a global variable contextFits*: bool # type/non-type context matches prefix*: PrefixMatch - localUsages*, globalUsages*: int # more usages is better + scope*, localUsages*, globalUsages*: int # more usages is better tokenLen*: int + Suggestions* = seq[Suggest] var suggestionResultHook*: proc (result: Suggest) {.closure.} @@ -68,26 +71,51 @@ template origModuleName(m: PSym): string = m.name.s proc findDocComment(n: PNode): PNode = if n == nil: return nil if not isNil(n.comment): return n - for i in countup(0, safeLen(n)-1): - result = findDocComment(n.sons[i]) + if n.kind in {nkStmtList, nkStmtListExpr} and n.len > 0: + result = findDocComment(n.sons[0]) if result != nil: return + if n.len > 1: + result = findDocComment(n.sons[1]) + elif n.kind in {nkAsgn, nkFastAsgn} and n.len == 2: + result = findDocComment(n.sons[1]) proc extractDocComment(s: PSym): string = - let n = findDocComment(s.ast) + var n = findDocComment(s.ast) + if n.isNil and s.kind in routineKinds and s.ast != nil: + n = findDocComment(s.ast[bodyPos]) if not n.isNil: result = n.comment.replace("\n##", "\n").strip else: result = "" +proc cmpSuggestions(a, b: Suggest): int = + template cf(field) {.dirty.} = + result = b.field.int - a.field.int + if result != 0: return result + + cf scope + cf prefix + # when the first type matches, it's better when it's a generic match: + cf quality + cf contextFits + cf localUsages + cf globalUsages + # if all is equal, sort alphabetically for deterministic output, + # independent of hashing order: + result = cmp(a.name.s, b.name.s) + proc symToSuggest(s: PSym, isLocal: bool, section: string, li: TLineInfo; quality: range[0..100]; prefix: PrefixMatch; - inTypeContext: bool): Suggest = + inTypeContext: bool; scope: int): Suggest = + new(result) result.section = parseIdeCmd(section) result.quality = quality result.isGlobal = sfGlobal in s.flags result.tokenLen = s.name.s.len result.prefix = prefix result.contextFits = inTypeContext == (s.kind in {skType, skGenericParam}) + result.scope = scope + result.name = s.name when defined(nimsuggest): result.globalUsages = s.allUsages.len var c = 0 @@ -161,8 +189,9 @@ proc `$`*(suggest: Suggest): string = result.add($suggest.prefix) proc symToSuggest(s: PSym, isLocal: bool, section: string; - quality: range[0..100], prefix: PrefixMatch; inTypeContext: bool): Suggest = - result = symToSuggest(s, isLocal, section, s.info, quality, prefix, inTypeContext) + quality: range[0..100], prefix: PrefixMatch; inTypeContext: bool; + scope: int): Suggest = + result = symToSuggest(s, isLocal, section, s.info, quality, prefix, inTypeContext, scope) proc suggestResult(s: Suggest) = if not isNil(suggestionResultHook): @@ -170,11 +199,21 @@ proc suggestResult(s: Suggest) = else: suggestWriteln($s) +proc produceOutput(a: var Suggestions) = + if gIdeCmd in {ideSug, ideCon}: + a.sort cmpSuggestions + if not isNil(suggestionResultHook): + for s in a: + suggestionResultHook(s) + else: + for s in a: + suggestWriteln($s) + proc filterSym(s: PSym; prefix: PNode; res: var PrefixMatch): bool {.inline.} = proc prefixMatch(s: PSym; n: PNode): PrefixMatch = case n.kind - of nkIdent: result = s.name.s.prefixMatch(n.ident.s) - of nkSym: result = s.name.s.prefixMatch(n.sym.name.s) + of nkIdent: result = n.ident.s.prefixMatch(s.name.s) + of nkSym: result = n.sym.name.s.prefixMatch(s.name.s) of nkOpenSymChoice, nkClosedSymChoice, nkAccQuoted: if n.len > 0: result = prefixMatch(s, n[0]) @@ -198,33 +237,38 @@ proc fieldVisible*(c: PContext, f: PSym): bool {.inline.} = result = true break -proc suggestField(c: PContext, s: PSym; f: PNode; outputs: var int) = +proc suggestField(c: PContext, s: PSym; f: PNode; outputs: var Suggestions) = var pm: PrefixMatch if filterSym(s, f, pm) and fieldVisible(c, s): - suggestResult(symToSuggest(s, isLocal=true, $ideSug, 100, pm, c.inTypeContext > 0)) - inc outputs + outputs.add(symToSuggest(s, isLocal=true, $ideSug, 100, pm, c.inTypeContext > 0, 0)) + +proc getQuality(s: PSym): range[0..100] = + if s.typ != nil and s.typ.len > 1: + var exp = s.typ.sons[1].skipTypes({tyGenericInst, tyVar, tyAlias}) + if exp.kind == tyVarargs: exp = elemType(exp) + if exp.kind in {tyExpr, tyStmt, tyGenericParam, tyAnything}: return 50 + return 100 template wholeSymTab(cond, section: untyped) = var isLocal = true + var scopeN = 0 for scope in walkScopes(c.currentScope): if scope == c.topLevelScope: isLocal = false - var entries = sequtils.toSeq(items(scope.symbols)) - sort(entries) do (a,b: PSym) -> int: - return cmp(a.name.s, b.name.s) - for item in entries: + dec scopeN + for item in scope.symbols: let it {.inject.} = item var pm {.inject.}: PrefixMatch if cond: - suggestResult(symToSuggest(it, isLocal = isLocal, section, 100, pm, c.inTypeContext > 0)) - inc outputs + outputs.add(symToSuggest(it, isLocal = isLocal, section, getQuality(it), + pm, c.inTypeContext > 0, scopeN)) -proc suggestSymList(c: PContext, list, f: PNode, outputs: var int) = +proc suggestSymList(c: PContext, list, f: PNode, outputs: var Suggestions) = for i in countup(0, sonsLen(list) - 1): if list.sons[i].kind == nkSym: suggestField(c, list.sons[i].sym, f, outputs) #else: InternalError(list.info, "getSymFromList") -proc suggestObject(c: PContext, n, f: PNode, outputs: var int) = +proc suggestObject(c: PContext, n, f: PNode, outputs: var Suggestions) = case n.kind of nkRecList: for i in countup(0, sonsLen(n)-1): suggestObject(c, n.sons[i], f, outputs) @@ -256,7 +300,7 @@ proc argsFit(c: PContext, candidate: PSym, n, nOrig: PNode): bool = else: result = false -proc suggestCall(c: PContext, n, nOrig: PNode, outputs: var int) = +proc suggestCall(c: PContext, n, nOrig: PNode, outputs: var Suggestions) = wholeSymTab(filterSym(it, nil, pm) and nameFits(c, it, n) and argsFit(c, it, n, nOrig), $ideCon) @@ -273,23 +317,24 @@ proc typeFits(c: PContext, s: PSym, firstArg: PType): bool {.inline.} = if exp.kind in {tyExpr, tyStmt, tyGenericParam, tyAnything}: return result = sigmatch.argtypeMatches(c, s.typ.sons[1], firstArg) -proc suggestOperations(c: PContext, n, f: PNode, typ: PType, outputs: var int) = +proc suggestOperations(c: PContext, n, f: PNode, typ: PType, outputs: var Suggestions) = assert typ != nil wholeSymTab(filterSymNoOpr(it, f, pm) and typeFits(c, it, typ), $ideSug) -proc suggestEverything(c: PContext, n, f: PNode, outputs: var int) = +proc suggestEverything(c: PContext, n, f: PNode, outputs: var Suggestions) = # do not produce too many symbols: var isLocal = true + var scopeN = 0 for scope in walkScopes(c.currentScope): if scope == c.topLevelScope: isLocal = false + dec scopeN for it in items(scope.symbols): var pm: PrefixMatch if filterSym(it, f, pm): - suggestResult(symToSuggest(it, isLocal = isLocal, $ideSug, 0, pm, c.inTypeContext > 0)) - inc outputs + outputs.add(symToSuggest(it, isLocal = isLocal, $ideSug, 0, pm, c.inTypeContext > 0, scopeN)) if scope == c.topLevelScope and f.isNil: break -proc suggestFieldAccess(c: PContext, n, field: PNode, outputs: var int) = +proc suggestFieldAccess(c: PContext, n, field: PNode, outputs: var Suggestions) = # special code that deals with ``myObj.``. `n` is NOT the nkDotExpr-node, but # ``myObj``. var typ = n.typ @@ -307,10 +352,9 @@ proc suggestFieldAccess(c: PContext, n, field: PNode, outputs: var int) = else: for it in items(n.sym.tab): if filterSym(it, field, pm): - suggestResult(symToSuggest(it, isLocal=false, $ideSug, 100, pm, c.inTypeContext > 0)) - inc outputs - suggestResult(symToSuggest(m, isLocal=false, $ideMod, 100, PrefixMatch.None, - c.inTypeContext > 0)) + outputs.add(symToSuggest(it, isLocal=false, $ideSug, 100, pm, c.inTypeContext > 0, -100)) + outputs.add(symToSuggest(m, isLocal=false, $ideMod, 100, PrefixMatch.None, + c.inTypeContext > 0, -99)) if typ == nil: # a module symbol has no type for example: @@ -319,13 +363,11 @@ proc suggestFieldAccess(c: PContext, n, field: PNode, outputs: var int) = # all symbols accessible, because we are in the current module: for it in items(c.topLevelScope.symbols): if filterSym(it, field, pm): - suggestResult(symToSuggest(it, isLocal=false, $ideSug, 100, pm, c.inTypeContext > 0)) - inc outputs + outputs.add(symToSuggest(it, isLocal=false, $ideSug, 100, pm, c.inTypeContext > 0, -99)) else: for it in items(n.sym.tab): if filterSym(it, field, pm): - suggestResult(symToSuggest(it, isLocal=false, $ideSug, 100, pm, c.inTypeContext > 0)) - inc outputs + outputs.add(symToSuggest(it, isLocal=false, $ideSug, 100, pm, c.inTypeContext > 0, -99)) else: # fallback: suggestEverything(c, n, field, outputs) @@ -408,17 +450,16 @@ when defined(nimsuggest): s.allUsages.add(info) var - #usageSym*: PSym lastLineInfo*: TLineInfo proc findUsages(info: TLineInfo; s: PSym; usageSym: var PSym) = if suggestVersion < 2: if usageSym == nil and isTracked(info, s.name.s.len): usageSym = s - suggestResult(symToSuggest(s, isLocal=false, $ideUse, 100, PrefixMatch.None, false)) + suggestResult(symToSuggest(s, isLocal=false, $ideUse, 100, PrefixMatch.None, false, 0)) elif s == usageSym: if lastLineInfo != info: - suggestResult(symToSuggest(s, isLocal=false, $ideUse, info, 100, PrefixMatch.None, false)) + suggestResult(symToSuggest(s, isLocal=false, $ideUse, info, 100, PrefixMatch.None, false, 0)) lastLineInfo = info when defined(nimsuggest): @@ -426,12 +467,12 @@ when defined(nimsuggest): #echo "usages ", len(s.allUsages) for info in s.allUsages: let x = if info == s.info and info.col == s.info.col: "def" else: "use" - suggestResult(symToSuggest(s, isLocal=false, x, info, 100, PrefixMatch.None, false)) + suggestResult(symToSuggest(s, isLocal=false, x, info, 100, PrefixMatch.None, false, 0)) proc findDefinition(info: TLineInfo; s: PSym) = if s.isNil: return if isTracked(info, s.name.s.len): - suggestResult(symToSuggest(s, isLocal=false, $ideDef, 100, PrefixMatch.None, false)) + suggestResult(symToSuggest(s, isLocal=false, $ideDef, 100, PrefixMatch.None, false, 0)) suggestQuit() proc ensureIdx[T](x: var T, y: int) = @@ -455,13 +496,13 @@ proc suggestSym*(info: TLineInfo; s: PSym; usageSym: var PSym; isDecl=true) {.in findDefinition(info, s) elif gIdeCmd == ideDus and s != nil: if isTracked(info, s.name.s.len): - suggestResult(symToSuggest(s, isLocal=false, $ideDef, 100, PrefixMatch.None, false)) + suggestResult(symToSuggest(s, isLocal=false, $ideDef, 100, PrefixMatch.None, false, 0)) findUsages(info, s, usageSym) elif gIdeCmd == ideHighlight and info.fileIndex == gTrackPos.fileIndex: - suggestResult(symToSuggest(s, isLocal=false, $ideHighlight, info, 100, PrefixMatch.None, false)) + suggestResult(symToSuggest(s, isLocal=false, $ideHighlight, info, 100, PrefixMatch.None, false, 0)) elif gIdeCmd == ideOutline and info.fileIndex == gTrackPos.fileIndex and isDecl: - suggestResult(symToSuggest(s, isLocal=false, $ideOutline, info, 100, PrefixMatch.None, false)) + suggestResult(symToSuggest(s, isLocal=false, $ideOutline, info, 100, PrefixMatch.None, false, 0)) proc markUsed(info: TLineInfo; s: PSym; usageSym: var PSym) = incl(s.flags, sfUsed) @@ -488,11 +529,11 @@ proc suggestExpr*(c: PContext, node: PNode) = if gTrackPos.line < 0: return var cp = inCheckpoint(node.info) if cp == cpNone: return - var outputs = 0 # This keeps semExpr() from coming here recursively: if c.compilesContextId > 0: return inc(c.compilesContextId) + var outputs: Suggestions = @[] if gIdeCmd == ideSug: var n = findClosestDot(node) if n == nil: n = node @@ -531,7 +572,9 @@ proc suggestExpr*(c: PContext, node: PNode) = suggestCall(c, a, n, outputs) dec(c.compilesContextId) - if outputs > 0 and gIdeCmd in {ideSug, ideCon, ideDef}: suggestQuit() + if outputs.len > 0 and gIdeCmd in {ideSug, ideCon, ideDef}: + produceOutput(outputs) + suggestQuit() proc suggestStmt*(c: PContext, n: PNode) = suggestExpr(c, n) @@ -542,11 +585,15 @@ proc suggestSentinel*(c: PContext) = inc(c.compilesContextId) # suggest everything: var isLocal = true + var outputs: Suggestions = @[] + var scopeN = 0 for scope in walkScopes(c.currentScope): if scope == c.topLevelScope: isLocal = false + dec scopeN for it in items(scope.symbols): var pm: PrefixMatch if filterSymNoOpr(it, nil, pm): - suggestResult(symToSuggest(it, isLocal = isLocal, $ideSug, 0, PrefixMatch.None, false)) + outputs.add(symToSuggest(it, isLocal = isLocal, $ideSug, 0, PrefixMatch.None, false, scopeN)) + produceOutput(outputs) dec(c.compilesContextId) diff --git a/tools/nimsuggest/nimsuggest.nim b/tools/nimsuggest/nimsuggest.nim index 628f2bc4c..1798ac4e9 100644 --- a/tools/nimsuggest/nimsuggest.nim +++ b/tools/nimsuggest/nimsuggest.nim @@ -17,7 +17,7 @@ import compiler / [options, commands, modules, sem, passes, passaux, msgs, nimconf, extccomp, condsyms, sigmatch, ast, scriptconfig, - idents, modulegraphs, vm] + idents, modulegraphs, vm, prefixmatches] when defined(windows): import winlean @@ -51,6 +51,11 @@ are supported. """ type Mode = enum mstdin, mtcp, mepc, mcmdline + CachedMsg = object + info: TLineInfo + msg: string + sev: Severity + CachedMsgs = seq[CachedMsg] var gPort = 6000.Port @@ -93,7 +98,7 @@ proc parseQuoted(cmd: string; outp: var string; start: int): int = i += parseUntil(cmd, outp, seps, i) result = i -proc sexp(s: IdeCmd|TSymKind): SexpNode = sexp($s) +proc sexp(s: IdeCmd|TSymKind|PrefixMatch): SexpNode = sexp($s) proc sexp(s: Suggest): SexpNode = # If you change the order here, make sure to change it over in @@ -110,6 +115,8 @@ proc sexp(s: Suggest): SexpNode = s.doc, s.quality ]) + if s.section == ideSug: + result.add convertSexp(s.prefix) proc sexp(s: seq[Suggest]): SexpNode = result = newSList() @@ -363,7 +370,7 @@ proc replEpc(x: ThreadParams) {.thread.} = "unexpected call: " & epcAPI quit errMessage -proc execCmd(cmd: string; graph: ModuleGraph; cache: IdentCache) = +proc execCmd(cmd: string; graph: ModuleGraph; cache: IdentCache; cachedMsgs: CachedMsgs) = template sentinel() = # send sentinel for the input reading thread: results.send(Suggest(section: ideNone)) @@ -415,17 +422,19 @@ proc execCmd(cmd: string; graph: ModuleGraph; cache: IdentCache) = if gIdeCmd == ideKnown: results.send(Suggest(section: ideKnown, quality: ord(fileInfoKnown(orig)))) else: + if gIdeCmd == ideChk: + for cm in cachedMsgs: errorHook(cm.info, cm.msg, cm.sev) execute(gIdeCmd, orig, dirtyfile, line, col-1, graph, cache) sentinel() proc recompileFullProject(graph: ModuleGraph; cache: IdentCache) = - echo "recompiling full project" + #echo "recompiling full project" resetSystemArtifacts() vm.globalCtx = nil graph.resetAllModules() GC_fullcollect() compileProject(graph, cache) - echo GC_getStatistics() + #echo GC_getStatistics() proc mainThread(graph: ModuleGraph; cache: IdentCache) = if gLogging: @@ -442,12 +451,13 @@ proc mainThread(graph: ModuleGraph; cache: IdentCache) = suggestionResultHook = sugResultHook graph.doStopCompile = proc (): bool = requests.peek() > 0 var idle = 0 + var cachedMsgs: CachedMsgs = @[] while true: let (hasData, req) = requests.tryRecv() if hasData: msgs.writelnHook = wrHook suggestionResultHook = sugResultHook - execCmd(req, graph, cache) + execCmd(req, graph, cache, cachedMsgs) idle = 0 else: os.sleep 250 @@ -456,7 +466,9 @@ proc mainThread(graph: ModuleGraph; cache: IdentCache) = # we use some nimsuggest activity to enable a lazy recompile: gIdeCmd = ideChk msgs.writelnHook = proc (s: string) = discard - msgs.structuredErrorHook = nil + cachedMsgs.setLen 0 + msgs.structuredErrorHook = proc (info: TLineInfo; msg: string; sev: Severity) = + cachedMsgs.add(CachedMsg(info: info, msg: msg, sev: sev)) suggestionResultHook = proc (s: Suggest) = discard recompileFullProject(graph, cache) @@ -525,8 +537,13 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string) = suggestVersion = 2 gMode = mstdin gEmitEof = true + gRefresh = false of "log": gLogging = true - of "refresh": gRefresh = true + of "refresh": + if p.val.len > 0: + gRefresh = parseBool(p.val) + else: + gRefresh = true else: processSwitch(pass, p) of cmdArgument: options.gProjectName = unixToNativePath(p.key) diff --git a/tools/nimsuggest/tester.nim b/tools/nimsuggest/tester.nim index 840d1e27c..0bee14254 100644 --- a/tools/nimsuggest/tester.nim +++ b/tools/nimsuggest/tester.nim @@ -20,6 +20,7 @@ template tpath(): untyped = getAppDir() / "tests" proc parseTest(filename: string; epcMode=false): Test = const cursorMarker = "#[!]#" let nimsug = curDir & addFileExt("nimsuggest", ExeExt) + let libpath = findExe("nim").splitFile().dir /../ "lib" result.dest = getTempDir() / extractFilename(filename) result.cmd = nimsug & " --tester " & result.dest result.script = @[] @@ -42,7 +43,7 @@ proc parseTest(filename: string; epcMode=false): Test = inc specSection elif specSection == 1: if x.startsWith("$nimsuggest"): - result.cmd = x % ["nimsuggest", nimsug, "file", filename] + result.cmd = x % ["nimsuggest", nimsug, "file", filename, "lib", libpath] elif x.startsWith("!"): if result.cmd.len == 0: result.startup.add x @@ -54,7 +55,7 @@ proc parseTest(filename: string; epcMode=false): Test = result.script.add((x.substr(1).replaceWord("$path", tpath()), "")) elif x.len > 0: # expected output line: - let x = x % ["file", filename] + let x = x % ["file", filename, "lib", libpath] result.script[^1][1].add x.replace(";;", "\t") & '\L' # else: ignore empty lines for better readability of the specs inc i @@ -203,6 +204,9 @@ proc sexpToAnswer(s: SexpNode): string = result.add doc result.add '\t' result.add a[8].getNum + if a.len >= 10: + result.add '\t' + result.add a[9].getStr result.add '\L' proc doReport(filename, answer, resp: string; report: var string) = diff --git a/tools/nimsuggest/tests/tno_deref.nim b/tools/nimsuggest/tests/tno_deref.nim index 0f8ba3bd8..05cffa507 100644 --- a/tools/nimsuggest/tests/tno_deref.nim +++ b/tools/nimsuggest/tests/tno_deref.nim @@ -9,6 +9,6 @@ x.#[!]# discard """ $nimsuggest --tester $file >sug $1 -sug;;skProc;;tno_deref.foo;;proc (y: ptr int)*;;$file;;4;;5;;"";;100 +sug;;skProc;;tno_deref.foo;;proc (y: ptr int)*;;$file;;4;;5;;"";;100;;None * """ diff --git a/tools/nimsuggest/tests/tsug_regression.nim b/tools/nimsuggest/tests/tsug_regression.nim new file mode 100644 index 000000000..1e440db2d --- /dev/null +++ b/tools/nimsuggest/tests/tsug_regression.nim @@ -0,0 +1,28 @@ +# test we only get suggestions, not error messages: + +import tables, sets, parsecfg + +type X = object + +proc main = + # bug #52 + var + set0 = initSet[int]() + set1 = initSet[X]() + set2 = initSet[ref int]() + + map0 = initTable[int, int]() + map1 = initOrderedTable[string, int]() + cfg = loadConfig("file") + map0.#[!]# + +discard """ +$nimsuggest --tester $file +>sug $1 +sug;;skProc;;tables.getOrDefault;;proc (t: Table[getOrDefault.A, getOrDefault.B], key: A): B;;$lib/pure/collections/tables.nim;;178;;5;;"";;100;;None +sug;;skProc;;tables.hasKey;;proc (t: Table[hasKey.A, hasKey.B], key: A): bool;;$lib/pure/collections/tables.nim;;233;;5;;"returns true iff `key` is in the table `t`.";;100;;None +sug;;skProc;;tables.add;;proc (t: var Table[add.A, add.B], key: A, val: B);;$lib/pure/collections/tables.nim;;297;;5;;"puts a new (key, value)-pair into `t` even if ``t[key]`` already exists.";;100;;None +sug;;skIterator;;tables.allValues;;iterator (t: Table[allValues.A, allValues.B], key: A): B{.inline.};;$lib/pure/collections/tables.nim;;225;;9;;"iterates over any value in the table `t` that belongs to the given `key`.";;100;;None +sug;;skProc;;tables.clear;;proc (t: var Table[clear.A, clear.B]);;$lib/pure/collections/tables.nim;;121;;5;;"Resets the table so that it is empty.";;100;;None +* +""" diff --git a/tools/nimsuggest/tests/twithin_macro.nim b/tools/nimsuggest/tests/twithin_macro.nim index 7392dd605..e0df03542 100644 --- a/tools/nimsuggest/tests/twithin_macro.nim +++ b/tools/nimsuggest/tests/twithin_macro.nim @@ -204,10 +204,10 @@ echo r discard """ $nimsuggest --tester $file >sug $1 -sug;;skField;;name;;string;;$file;;166;;6;;"";;100 -sug;;skField;;age;;int;;$file;;167;;6;;"";;100 -sug;;skMethod;;twithin_macro.age_human_yrs;;proc (self: Animal): int;;$file;;169;;9;;"";;100 -sug;;skMacro;;twithin_macro.class;;proc (head: untyped, body: untyped): untyped{.gcsafe, locks: <unknown>.};;$file;;4;;6;;"Iterates over the children of the NimNode ``n``.";;100 -sug;;skMethod;;twithin_macro.vocalize;;proc (self: Animal): string;;$file;;168;;9;;"";;100 -sug;;skMethod;;twithin_macro.vocalize;;proc (self: Rabbit): string;;$file;;184;;9;;"";;100* +sug;;skField;;age;;int;;$file;;167;;6;;"";;100;;None +sug;;skField;;name;;string;;$file;;166;;6;;"";;100;;None +sug;;skMethod;;twithin_macro.age_human_yrs;;proc (self: Animal): int;;$file;;169;;9;;"";;100;;None +sug;;skMethod;;twithin_macro.vocalize;;proc (self: Animal): string;;$file;;168;;9;;"";;100;;None +sug;;skMethod;;twithin_macro.vocalize;;proc (self: Rabbit): string;;$file;;184;;9;;"";;100;;None +sug;;skMacro;;twithin_macro.class;;proc (head: untyped, body: untyped): untyped{.gcsafe, locks: <unknown>.};;$file;;4;;6;;"";;50;;None* """ diff --git a/tools/nimsuggest/tests/twithin_macro_prefix.nim b/tools/nimsuggest/tests/twithin_macro_prefix.nim index 6ee9fb2dc..86e406c5d 100644 --- a/tools/nimsuggest/tests/twithin_macro_prefix.nim +++ b/tools/nimsuggest/tests/twithin_macro_prefix.nim @@ -204,6 +204,6 @@ echo r discard """ $nimsuggest --tester $file >sug $1 -sug;;skField;;age;;int;;$file;;167;;6;;"";;100 -sug;;skMethod;;twithin_macro_prefix.age_human_yrs;;proc (self: Animal): int;;$file;;169;;9;;"";;100 +sug;;skField;;age;;int;;$file;;167;;6;;"";;100;;Prefix +sug;;skMethod;;twithin_macro_prefix.age_human_yrs;;proc (self: Animal): int;;$file;;169;;9;;"";;100;;Prefix """ |