mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-19 15:31:28 +00:00
nimsuggest supports EPC protocol again; tester can test the EPC protocol
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user