diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2016-11-05 22:56:33 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2016-11-05 22:56:33 +0100 |
commit | eb2455075e73757db31aef4ef334714ce40d6662 (patch) | |
tree | c54aef9ef96fbba1fa5538577e61a711f979b9ca /tools/nimsuggest | |
parent | a644471b1218ea2ae9bfda83bb1fd78649ee68e7 (diff) | |
download | Nim-eb2455075e73757db31aef4ef334714ce40d6662.tar.gz |
nimsuggest & tester: many improvements, test new dependency tracking
Diffstat (limited to 'tools/nimsuggest')
-rw-r--r-- | tools/nimsuggest/nimsuggest.nim | 10 | ||||
-rw-r--r-- | tools/nimsuggest/tester.nim | 86 | ||||
-rw-r--r-- | tools/nimsuggest/tests/dep_v1.nim | 8 | ||||
-rw-r--r-- | tools/nimsuggest/tests/dep_v2.nim | 9 | ||||
-rw-r--r-- | tools/nimsuggest/tests/tdot2.nim | 2 | ||||
-rw-r--r-- | tools/nimsuggest/tests/tdot3.nim | 27 |
6 files changed, 127 insertions, 15 deletions
diff --git a/tools/nimsuggest/nimsuggest.nim b/tools/nimsuggest/nimsuggest.nim index f00d9b636..6b7ee74e2 100644 --- a/tools/nimsuggest/nimsuggest.nim +++ b/tools/nimsuggest/nimsuggest.nim @@ -60,7 +60,7 @@ var const seps = {':', ';', ' ', '\t'} - Help = "usage: sug|con|def|use|dus|chk|highlight|outline file.nim[;dirtyfile.nim]:line:col\n" & + Help = "usage: sug|con|def|use|dus|chk|mod|highlight|outline file.nim[;dirtyfile.nim]:line:col\n" & "type 'quit' to quit\n" & "type 'debug' to toggle debug mode on/off\n" & "type 'terse' to toggle terse mode on/off" @@ -104,13 +104,13 @@ proc sexp(s: seq[Suggest]): SexpNode = for sug in s: result.add(sexp(sug)) -proc listEPC(): SexpNode = +proc listEpc(): SexpNode = # This function is called from Emacs to show available options. let argspecs = sexp("file line column dirtyfile".split(" ").map(newSSymbol)) docstring = sexp("line starts at 1, column at 0, dirtyfile is optional") result = newSList() - for command in ["sug", "con", "def", "use", "dus", "chk"]: + for command in ["sug", "con", "def", "use", "dus", "chk", "mod"]: let cmd = sexp(command) methodDesc = newSList() @@ -162,7 +162,8 @@ proc execute(cmd: IdeCmd, file, dirtyfile: string, line, col: int; # resetModule gProjectMainIdx graph.markDirty dirtyIdx graph.markClientsDirty dirtyIdx - graph.compileProject(cache, dirtyIdx) + if gIdeCmd != ideMod: + graph.compileProject(cache, dirtyIdx) if gIdeCmd in {ideUse, ideDus}: let u = if suggestVersion >= 2: graph.symFromInfo(gTrackPos) else: usageSym if u != nil: @@ -238,6 +239,7 @@ proc parseCmdLine(cmd: string; graph: ModuleGraph; cache: IdentCache) = of "def": gIdeCmd = ideDef of "use": gIdeCmd = ideUse of "dus": gIdeCmd = ideDus + of "mod": gIdeCmd = ideMod of "chk": gIdeCmd = ideChk incl(gGlobalOptions, optIdeDebug) diff --git a/tools/nimsuggest/tester.nim b/tools/nimsuggest/tester.nim index b4e1f8f7f..c90afe3db 100644 --- a/tools/nimsuggest/tester.nim +++ b/tools/nimsuggest/tester.nim @@ -8,18 +8,22 @@ import os, osproc, strutils, streams, re type Test = object cmd, dest: string + startup: seq[string] script: seq[(string, string)] const curDir = when defined(windows): "" else: "" DummyEof = "!EOF!" +template tpath(): untyped = getAppDir() / "tests" + proc parseTest(filename: string): Test = const cursorMarker = "#[!]#" let nimsug = curDir & addFileExt("nimsuggest", ExeExt) result.dest = getTempDir() / extractFilename(filename) result.cmd = nimsug & " --tester " & result.dest result.script = @[] + result.startup = @[] var tmp = open(result.dest, fmWrite) var specSection = 0 var markers = newSeq[string]() @@ -36,25 +40,56 @@ proc parseTest(filename: string): Test = elif specSection == 1: if x.startsWith("$nimsuggest"): result.cmd = x % ["nimsuggest", nimsug, "file", filename] - elif x.startsWith("!edit"): - result.script.add((x, "")) + elif x.startsWith("!"): + if result.cmd.len == 0: + result.startup.add x + else: + result.script.add((x, "")) elif x.startsWith(">"): # since 'markers' here are not complete yet, we do the $substitutions # afterwards - result.script.add((x.substr(1), "")) - else: + result.script.add((x.substr(1).replaceWord("$path", tpath()), "")) + elif x.len > 0: # expected output line: let x = x % ["file", filename] result.script[^1][1].add x.replace(";;", "\t") & '\L' + # else: ignore empty lines for better readability of the specs inc i tmp.close() # now that we know the markers, substitute them: for a in mitems(result.script): a[0] = a[0] % markers -proc edit(tmpfile, cmd: string) = - let x = cmd.splitWhitespace() - let f = if x.len >= 4: x[3] else: tmpfile +proc parseCmd(c: string): seq[string] = + # we don't support double quotes for now so that + # we can later support them properly with escapes and stuff. + result = @[] + var i = 0 + var a = "" + while true: + setLen(a, 0) + # eat all delimiting whitespace + while c[i] in {' ', '\t', '\l', '\r'}: inc(i) + case c[i] + of '"': raise newException(ValueError, "double quotes not yet supported: " & c) + of '\'': + var delim = c[i] + inc(i) # skip ' or " + while c[i] != '\0' and c[i] != delim: + add a, c[i] + inc(i) + if c[i] != '\0': inc(i) + of '\0': break + else: + while c[i] > ' ': + add(a, c[i]) + inc(i) + add(result, a) + +proc edit(tmpfile: string; x: seq[string]) = + if x.len != 3 and x.len != 4: + quit "!edit takes two or three arguments" + let f = if x.len >= 4: tpath() / x[3] else: tmpfile try: let content = readFile(f) let newcontent = content.replace(x[1], x[2]) @@ -64,12 +99,45 @@ proc edit(tmpfile, cmd: string) = except IOError: quit "cannot edit file " & tmpfile +proc exec(x: seq[string]) = + if x.len != 2: quit "!exec takes one argument" + if execShellCmd(x[1]) != 0: + quit "External program failed " & x[1] + +proc copy(x: seq[string]) = + if x.len != 3: quit "!copy takes two arguments" + let rel = tpath() + copyFile(rel / x[1], rel / x[2]) + +proc del(x: seq[string]) = + if x.len != 2: quit "!del takes one argument" + removeFile(tpath() / x[1]) + +proc runCmd(cmd, dest: string): bool = + result = cmd[0] == '!' + if not result: return + let x = cmd.parseCmd() + case x[0] + of "!edit": + edit(dest, x) + of "!exec": + exec(x) + of "!copy": + copy(x) + of "!del": + del(x) + else: + quit "unkown command: " & cmd + proc smartCompare(pattern, x: string): bool = if pattern.contains('*'): result = match(x, re(escapeRe(pattern).replace("\\x2A","(.*)"), {})) proc runTest(filename: string): int = let s = parseTest filename + for cmd in s.startup: + if not runCmd(cmd, s.dest): + quit "invalid command: " & cmd let cl = parseCmdLine(s.cmd) var p = startProcess(command=cl[0], args=cl[1 .. ^1], options={poStdErrToStdOut, poUsePath, @@ -83,9 +151,7 @@ proc runTest(filename: string): int = while outp.readLine(a): if a == DummyEof: break for req, resp in items(s.script): - if req.startsWith("!edit"): - edit(s.dest, req) - else: + if not runCmd(req, s.dest): inp.writeLine(req) inp.flush() var answer = "" diff --git a/tools/nimsuggest/tests/dep_v1.nim b/tools/nimsuggest/tests/dep_v1.nim new file mode 100644 index 000000000..eae230e85 --- /dev/null +++ b/tools/nimsuggest/tests/dep_v1.nim @@ -0,0 +1,8 @@ + + + + + +type + Foo* = object + x*, y*: int diff --git a/tools/nimsuggest/tests/dep_v2.nim b/tools/nimsuggest/tests/dep_v2.nim new file mode 100644 index 000000000..ab39721c4 --- /dev/null +++ b/tools/nimsuggest/tests/dep_v2.nim @@ -0,0 +1,9 @@ + + + + + +type + Foo* = object + x*, y*: int + z*: string diff --git a/tools/nimsuggest/tests/tdot2.nim b/tools/nimsuggest/tests/tdot2.nim index 490e78451..a58ac818b 100644 --- a/tools/nimsuggest/tests/tdot2.nim +++ b/tools/nimsuggest/tests/tdot2.nim @@ -1,4 +1,4 @@ -# Test that basic editing. We replace the 'false' by 'true' to +# Test basic editing. We replace the 'false' by 'true' to # see whether then the z field is suggested. const zField = 0i32 diff --git a/tools/nimsuggest/tests/tdot3.nim b/tools/nimsuggest/tests/tdot3.nim new file mode 100644 index 000000000..5badde867 --- /dev/null +++ b/tools/nimsuggest/tests/tdot3.nim @@ -0,0 +1,27 @@ +# Test basic module dependency recompilations. + +import dep + +proc main(f: Foo) = + f.#[!]# + +# the tester supports the spec section at the bottom of the file and +# this way, the line numbers more often stay the same + +discard """ +!copy dep_v1.nim dep.nim +$nimsuggest --tester $file +>sug $1 +sug;;skField;;x;;int;;*dep.nim;;8;;4;;"";;100 +sug;;skField;;y;;int;;*dep.nim;;8;;8;;"";;100 +sug;;skProc;;tdot3.main;;proc (f: Foo);;$file;;5;;5;;"";;100 + +!copy dep_v2.nim dep.nim +>mod $path/dep.nim +>sug $1 +sug;;skField;;x;;int;;*dep.nim;;8;;4;;"";;100 +sug;;skField;;y;;int;;*dep.nim;;8;;8;;"";;100 +sug;;skField;;z;;string;;*dep.nim;;9;;4;;"";;100 +sug;;skProc;;tdot3.main;;proc (f: Foo);;$file;;5;;5;;"";;100 +!del dep.nim +""" |