nimsuggest supports EPC protocol again; tester can test the EPC protocol
This commit is contained in:
parent
ba29ca0c63
commit
2adb4ce9eb
3 changed files with 130 additions and 12 deletions
|
|
@ -192,7 +192,7 @@ template sendEpc(results: typed, tdef, hook: untyped) =
|
||||||
let res = sexp(results)
|
let res = sexp(results)
|
||||||
if gLogging:
|
if gLogging:
|
||||||
logStr($res)
|
logStr($res)
|
||||||
returnEPC(client, uid, res)
|
returnEpc(client, uid, res)
|
||||||
|
|
||||||
template checkSanity(client, sizeHex, size, messageBuffer: typed) =
|
template checkSanity(client, sizeHex, size, messageBuffer: typed) =
|
||||||
if client.recv(sizeHex, 6) != 6:
|
if client.recv(sizeHex, 6) != 6:
|
||||||
|
|
@ -233,7 +233,7 @@ proc toEpc(client: Socket; uid: BiggestInt) {.gcsafe.} =
|
||||||
else:
|
else:
|
||||||
list.add sexp(res)
|
list.add sexp(res)
|
||||||
if gIdeCmd != ideChk:
|
if gIdeCmd != ideChk:
|
||||||
returnEPC(client, uid, list)
|
returnEpc(client, uid, list)
|
||||||
|
|
||||||
proc writelnToChannel(line: string) =
|
proc writelnToChannel(line: string) =
|
||||||
results.send(Suggest(section: ideChk, doc: line))
|
results.send(Suggest(section: ideChk, doc: line))
|
||||||
|
|
@ -303,8 +303,8 @@ proc replEpc(x: ThreadParams) {.thread.} =
|
||||||
checkSanity(client, sizeHex, size, messageBuffer)
|
checkSanity(client, sizeHex, size, messageBuffer)
|
||||||
let
|
let
|
||||||
message = parseSexp($messageBuffer)
|
message = parseSexp($messageBuffer)
|
||||||
epcAPI = message[0].getSymbol
|
epcApi = message[0].getSymbol
|
||||||
case epcAPI:
|
case epcApi
|
||||||
of "call":
|
of "call":
|
||||||
let
|
let
|
||||||
uid = message[1].getNum
|
uid = message[1].getNum
|
||||||
|
|
@ -320,16 +320,18 @@ proc replEpc(x: ThreadParams) {.thread.} =
|
||||||
of ideSug, ideCon, ideDef, ideUse, ideDus, ideOutline, ideHighlight:
|
of ideSug, ideCon, ideDef, ideUse, ideDus, ideOutline, ideHighlight:
|
||||||
setVerbosity(0)
|
setVerbosity(0)
|
||||||
else: discard
|
else: discard
|
||||||
requests.send messageBuffer
|
if gLogging:
|
||||||
|
logStr "MSG ARG: " & args.getStr
|
||||||
|
requests.send($gIdeCmd & " " & args.getStr)
|
||||||
toEpc(client, uid)
|
toEpc(client, uid)
|
||||||
of "methods":
|
of "methods":
|
||||||
returnEpc(client, message[1].getNum, listEPC())
|
returnEpc(client, message[1].getNum, listEpc())
|
||||||
of "epc-error":
|
of "epc-error":
|
||||||
# an unhandled exception forces down the whole process anyway, so we
|
# an unhandled exception forces down the whole process anyway, so we
|
||||||
# use 'quit' here instead of 'raise'
|
# use 'quit' here instead of 'raise'
|
||||||
quit("recieved epc error: " & $messageBuffer)
|
quit("recieved epc error: " & $messageBuffer)
|
||||||
else:
|
else:
|
||||||
let errMessage = case epcAPI
|
let errMessage = case epcApi
|
||||||
of "return", "return-error":
|
of "return", "return-error":
|
||||||
"no return expected"
|
"no return expected"
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -561,16 +561,16 @@ proc toPretty(result: var string, node: SexpNode, indent = 2, ml = true,
|
||||||
result.add(escapeJson(node.str))
|
result.add(escapeJson(node.str))
|
||||||
of SInt:
|
of SInt:
|
||||||
if lstArr: result.indent(currIndent)
|
if lstArr: result.indent(currIndent)
|
||||||
result.add($node.num)
|
result.add(node.num)
|
||||||
of SFloat:
|
of SFloat:
|
||||||
if lstArr: result.indent(currIndent)
|
if lstArr: result.indent(currIndent)
|
||||||
result.add($node.fnum)
|
result.add(node.fnum)
|
||||||
of SNil:
|
of SNil:
|
||||||
if lstArr: result.indent(currIndent)
|
if lstArr: result.indent(currIndent)
|
||||||
result.add("nil")
|
result.add("nil")
|
||||||
of SSymbol:
|
of SSymbol:
|
||||||
if lstArr: result.indent(currIndent)
|
if lstArr: result.indent(currIndent)
|
||||||
result.add($node.symbol)
|
result.add(node.symbol)
|
||||||
of SList:
|
of SList:
|
||||||
if lstArr: result.indent(currIndent)
|
if lstArr: result.indent(currIndent)
|
||||||
if len(node.elems) != 0:
|
if len(node.elems) != 0:
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
# before 'nimsuggest' is invoked to ensure this token doesn't make a
|
# before 'nimsuggest' is invoked to ensure this token doesn't make a
|
||||||
# crucial difference for Nim's parser.
|
# crucial difference for Nim's parser.
|
||||||
|
|
||||||
import os, osproc, strutils, streams, re
|
import os, osproc, strutils, streams, re, sexp, net
|
||||||
|
|
||||||
type
|
type
|
||||||
Test = object
|
Test = object
|
||||||
|
|
@ -133,6 +133,119 @@ proc smartCompare(pattern, x: string): bool =
|
||||||
if pattern.contains('*'):
|
if pattern.contains('*'):
|
||||||
result = match(x, re(escapeRe(pattern).replace("\\x2A","(.*)"), {}))
|
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 =
|
proc runTest(filename: string): int =
|
||||||
let s = parseTest filename
|
let s = parseTest filename
|
||||||
for cmd in s.startup:
|
for cmd in s.startup:
|
||||||
|
|
@ -176,6 +289,7 @@ proc runTest(filename: string): int =
|
||||||
inp.flush()
|
inp.flush()
|
||||||
close(p)
|
close(p)
|
||||||
if report.len > 0:
|
if report.len > 0:
|
||||||
|
echo "==== STDIN ======================================"
|
||||||
echo report
|
echo report
|
||||||
result = report.len
|
result = report.len
|
||||||
|
|
||||||
|
|
@ -183,7 +297,9 @@ proc main() =
|
||||||
var failures = 0
|
var failures = 0
|
||||||
for x in walkFiles(getAppDir() / "tests/t*.nim"):
|
for x in walkFiles(getAppDir() / "tests/t*.nim"):
|
||||||
echo "Test ", x
|
echo "Test ", x
|
||||||
failures += runTest(expandFilename(x))
|
let xx = expandFilename x
|
||||||
|
failures += runTest(xx)
|
||||||
|
failures += runEpcTest(xx)
|
||||||
if failures > 0:
|
if failures > 0:
|
||||||
quit 1
|
quit 1
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue