nimsuggest supports EPC protocol again; tester can test the EPC protocol

This commit is contained in:
Andreas Rumpf
2017-02-19 21:29:41 +01:00
parent ba29ca0c63
commit 2adb4ce9eb
3 changed files with 130 additions and 12 deletions

View File

@@ -192,7 +192,7 @@ template sendEpc(results: typed, tdef, hook: untyped) =
let res = sexp(results)
if gLogging:
logStr($res)
returnEPC(client, uid, res)
returnEpc(client, uid, res)
template checkSanity(client, sizeHex, size, messageBuffer: typed) =
if client.recv(sizeHex, 6) != 6:
@@ -233,7 +233,7 @@ proc toEpc(client: Socket; uid: BiggestInt) {.gcsafe.} =
else:
list.add sexp(res)
if gIdeCmd != ideChk:
returnEPC(client, uid, list)
returnEpc(client, uid, list)
proc writelnToChannel(line: string) =
results.send(Suggest(section: ideChk, doc: line))
@@ -303,8 +303,8 @@ proc replEpc(x: ThreadParams) {.thread.} =
checkSanity(client, sizeHex, size, messageBuffer)
let
message = parseSexp($messageBuffer)
epcAPI = message[0].getSymbol
case epcAPI:
epcApi = message[0].getSymbol
case epcApi
of "call":
let
uid = message[1].getNum
@@ -320,16 +320,18 @@ proc replEpc(x: ThreadParams) {.thread.} =
of ideSug, ideCon, ideDef, ideUse, ideDus, ideOutline, ideHighlight:
setVerbosity(0)
else: discard
requests.send messageBuffer
if gLogging:
logStr "MSG ARG: " & args.getStr
requests.send($gIdeCmd & " " & args.getStr)
toEpc(client, uid)
of "methods":
returnEpc(client, message[1].getNum, listEPC())
returnEpc(client, message[1].getNum, listEpc())
of "epc-error":
# an unhandled exception forces down the whole process anyway, so we
# use 'quit' here instead of 'raise'
quit("recieved epc error: " & $messageBuffer)
else:
let errMessage = case epcAPI
let errMessage = case epcApi
of "return", "return-error":
"no return expected"
else:

View File

@@ -561,16 +561,16 @@ proc toPretty(result: var string, node: SexpNode, indent = 2, ml = true,
result.add(escapeJson(node.str))
of SInt:
if lstArr: result.indent(currIndent)
result.add($node.num)
result.add(node.num)
of SFloat:
if lstArr: result.indent(currIndent)
result.add($node.fnum)
result.add(node.fnum)
of SNil:
if lstArr: result.indent(currIndent)
result.add("nil")
of SSymbol:
if lstArr: result.indent(currIndent)
result.add($node.symbol)
result.add(node.symbol)
of SList:
if lstArr: result.indent(currIndent)
if len(node.elems) != 0:

View File

@@ -3,7 +3,7 @@
# before 'nimsuggest' is invoked to ensure this token doesn't make a
# crucial difference for Nim's parser.
import os, osproc, strutils, streams, re
import os, osproc, strutils, streams, re, sexp, net
type
Test = object
@@ -133,6 +133,119 @@ proc smartCompare(pattern, x: string): bool =
if pattern.contains('*'):
result = match(x, re(escapeRe(pattern).replace("\\x2A","(.*)"), {}))
proc sendEpcStr(socket: Socket; cmd: string) =
let s = cmd.find(' ')
doAssert s > 0
let cmd = "(call 567 " & cmd.substr(0, s) & escapeJson(cmd.substr(s+1)) & ")"
socket.send toHex(cmd.len, 6)
socket.send cmd
proc recvEpc(socket: Socket): string =
var L = newStringOfCap(6)
if socket.recv(L, 6) != 6:
raise newException(ValueError, "recv A failed")
let x = parseHexInt(L)
result = newString(x)
if socket.recv(result, x) != x:
raise newException(ValueError, "recv B failed")
proc sexpToAnswer(s: SexpNode): string =
result = ""
doAssert s.kind == SList
doAssert s.len >= 3
let m = s[2]
if m.kind != SList:
echo s
doAssert m.kind == SList
for a in m:
doAssert a.kind == SList
var first = true
#s.section,
#s.symkind,
#s.qualifiedPath.map(newSString),
#s.filePath,
#s.forth,
#s.line,
#s.column,
#s.doc
if a.len >= 8:
let section = a[0].getStr
let symk = a[1].getStr
let qp = a[2]
let file = a[3].getStr
let typ = a[4].getStr
let line = a[5].getNum
let col = a[6].getNum
let doc = a[7].getStr.escapeJson
result.add section
result.add '\t'
result.add symk
result.add '\t'
var i = 0
for aa in qp:
if i > 0: result.add '.'
result.add aa.getStr
inc i
result.add '\t'
result.add typ
result.add '\t'
result.add file
result.add '\t'
result.add line
result.add '\t'
result.add col
result.add '\t'
result.add doc
result.add '\t'
# for now Nim EPC does not return the quality
result.add "100"
result.add '\L'
proc runEpcTest(filename: string): int =
let s = parseTest filename
for cmd in s.startup:
if not runCmd(cmd, s.dest):
quit "invalid command: " & cmd
let epccmd = s.cmd.replace("--tester", "--epc --v2")
let cl = parseCmdLine(epccmd)
var p = startProcess(command=cl[0], args=cl[1 .. ^1],
options={poStdErrToStdOut, poUsePath,
poInteractive, poDemon})
let outp = p.outputStream
let inp = p.inputStream
var report = ""
var a = newStringOfCap(120)
try:
# read the port number:
if outp.readLine(a):
let port = parseInt(a)
var socket = newSocket()
socket.connect("localhost", Port(port))
for req, resp in items(s.script):
if not runCmd(req, s.dest):
socket.sendEpcStr(req)
var answer = sexpToAnswer(parseSexp(socket.recvEpc()))
if resp != answer and not smartCompare(resp, answer):
report.add "\nTest failed: " & filename
var hasDiff = false
for i in 0..min(resp.len-1, answer.len-1):
if resp[i] != answer[i]:
report.add "\n Expected: " & resp.substr(i)
report.add "\n But got: " & answer.substr(i)
hasDiff = true
break
if not hasDiff:
report.add "\n Expected: " & resp
report.add "\n But got: " & answer
else:
raise newException(ValueError, "cannot read port number")
finally:
close(p)
if report.len > 0:
echo "==== EPC ========================================"
echo report
result = report.len
proc runTest(filename: string): int =
let s = parseTest filename
for cmd in s.startup:
@@ -176,6 +289,7 @@ proc runTest(filename: string): int =
inp.flush()
close(p)
if report.len > 0:
echo "==== STDIN ======================================"
echo report
result = report.len
@@ -183,7 +297,9 @@ proc main() =
var failures = 0
for x in walkFiles(getAppDir() / "tests/t*.nim"):
echo "Test ", x
failures += runTest(expandFilename(x))
let xx = expandFilename x
failures += runTest(xx)
failures += runEpcTest(xx)
if failures > 0:
quit 1