12 changes: 8 additions & 4 deletions lib/pure/options.nim
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ supports pattern matching on `Option`s, with the `Some(<pattern>)` and
]##
# xxx pending https://github.com/timotheecour/Nim/issues/376 use `runnableExamples` and `whichModule`

when defined(nimHasEffectsOf):
{.experimental: "strictEffects".}
else:
{.pragma: effectsOf.}

import typetraits

Expand Down Expand Up @@ -222,7 +226,7 @@ proc get*[T](self: var Option[T]): var T {.inline.} =
raise newException(UnpackDefect, "Can't obtain a value from a `none`")
return self.val

proc map*[T](self: Option[T], callback: proc (input: T)) {.inline.} =
proc map*[T](self: Option[T], callback: proc (input: T)) {.inline, effectsOf: callback.} =
## Applies a `callback` function to the value of the `Option`, if it has one.
##
## **See also:**
Expand All @@ -241,7 +245,7 @@ proc map*[T](self: Option[T], callback: proc (input: T)) {.inline.} =
if self.isSome:
callback(self.val)

proc map*[T, R](self: Option[T], callback: proc (input: T): R): Option[R] {.inline.} =
proc map*[T, R](self: Option[T], callback: proc (input: T): R): Option[R] {.inline, effectsOf: callback.} =
## Applies a `callback` function to the value of the `Option` and returns an
## `Option` containing the new value.
##
Expand Down Expand Up @@ -278,7 +282,7 @@ proc flatten*[T](self: Option[Option[T]]): Option[T] {.inline.} =
none(T)

proc flatMap*[T, R](self: Option[T],
callback: proc (input: T): Option[R]): Option[R] {.inline.} =
callback: proc (input: T): Option[R]): Option[R] {.inline, effectsOf: callback.} =
## Applies a `callback` function to the value of the `Option` and returns the new value.
##
## If the `Option` has no value, `none(R)` will be returned.
Expand All @@ -303,7 +307,7 @@ proc flatMap*[T, R](self: Option[T],

map(self, callback).flatten()

proc filter*[T](self: Option[T], callback: proc (input: T): bool): Option[T] {.inline.} =
proc filter*[T](self: Option[T], callback: proc (input: T): bool): Option[T] {.inline, effectsOf: callback.} =
## Applies a `callback` to the value of the `Option`.
##
## If the `callback` returns `true`, the option is returned as `some`.
Expand Down
12 changes: 6 additions & 6 deletions lib/pure/parsesql.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1451,7 +1451,7 @@ proc ra(n: SqlNode, s: var SqlWriter) =
s.addKeyw("enum")
rs(n, s)

proc renderSQL*(n: SqlNode, upperCase = false): string =
proc renderSql*(n: SqlNode, upperCase = false): string =
## Converts an SQL abstract syntax tree to its string representation.
var s: SqlWriter
s.buffer = ""
Expand All @@ -1460,8 +1460,8 @@ proc renderSQL*(n: SqlNode, upperCase = false): string =
return s.buffer

proc `$`*(n: SqlNode): string =
## an alias for `renderSQL`.
renderSQL(n)
## an alias for `renderSql`.
renderSql(n)

proc treeReprAux(s: SqlNode, level: int, result: var string) =
result.add('\n')
Expand Down Expand Up @@ -1493,7 +1493,7 @@ proc open(p: var SqlParser, input: Stream, filename: string) =
p.tok.literal = ""
getTok(p)

proc parseSQL*(input: Stream, filename: string): SqlNode =
proc parseSql*(input: Stream, filename: string): SqlNode =
## parses the SQL from `input` into an AST and returns the AST.
## `filename` is only used for error messages.
## Syntax errors raise an `SqlParseError` exception.
Expand All @@ -1504,8 +1504,8 @@ proc parseSQL*(input: Stream, filename: string): SqlNode =
finally:
close(p)

proc parseSQL*(input: string, filename = ""): SqlNode =
proc parseSql*(input: string, filename = ""): SqlNode =
## parses the SQL from `input` into an AST and returns the AST.
## `filename` is only used for error messages.
## Syntax errors raise an `SqlParseError` exception.
parseSQL(newStringStream(input), "")
parseSql(newStringStream(input), "")
9 changes: 6 additions & 3 deletions lib/pure/pegs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -836,10 +836,13 @@ template matchOrParse(mopProc: untyped) =
var idx = c.ml # reserve a slot for the subpattern
result = mopProc(s, p.sons[0], start, c)
if result >= 0:
inc(c.ml)
if idx < MaxSubpatterns:
if idx != c.ml:
for i in countdown(c.ml, idx):
c.matches[i+1] = c.matches[i]
c.matches[idx] = (start, start+result-1)
#else: silently ignore the capture
inc(c.ml)
leave(pkCapture, s, p, start, result)
of pkBackRef:
enter(pkBackRef, s, p, start)
Expand Down Expand Up @@ -1021,7 +1024,7 @@ template eventParser*(pegAst, handlers: untyped): (proc(s: string): int) =
## Symbols declared in an *enter* handler can be made visible in the
## corresponding *leave* handler by annotating them with an *inject* pragma.
proc rawParse(s: string, p: Peg, start: int, c: var Captures): int
{.genSym.} =
{.gensym.} =

# binding from *macros*
bind strVal
Expand Down Expand Up @@ -1056,7 +1059,7 @@ template eventParser*(pegAst, handlers: untyped): (proc(s: string): int) =
matchOrParse(parseIt)
parseIt(s, p, start, c)

proc parser(s: string): int {.genSym.} =
proc parser(s: string): int {.gensym.} =
# the proc to be returned
var
ms: array[MaxSubpatterns, (int, int)]
Expand Down
31 changes: 16 additions & 15 deletions lib/pure/punycode.nim
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const
type
PunyError* = object of ValueError

proc decodeDigit(x: char): int {.raises: [PunyError].} =
func decodeDigit(x: char): int {.raises: [PunyError].} =
if '0' <= x and x <= '9':
result = ord(x) - (ord('0') - 26)
elif 'A' <= x and x <= 'Z':
Expand All @@ -38,18 +38,18 @@ proc decodeDigit(x: char): int {.raises: [PunyError].} =
else:
raise newException(PunyError, "Bad input")

proc encodeDigit(digit: int): Rune {.raises: [PunyError].} =
func encodeDigit(digit: int): Rune {.raises: [PunyError].} =
if 0 <= digit and digit < 26:
result = Rune(digit + ord('a'))
elif 26 <= digit and digit < 36:
result = Rune(digit + (ord('0') - 26))
else:
raise newException(PunyError, "internal error in punycode encoding")

proc isBasic(c: char): bool = ord(c) < 0x80
proc isBasic(r: Rune): bool = int(r) < 0x80
func isBasic(c: char): bool = ord(c) < 0x80
func isBasic(r: Rune): bool = int(r) < 0x80

proc adapt(delta, numPoints: int, first: bool): int =
func adapt(delta, numPoints: int, first: bool): int =
var d = if first: delta div Damp else: delta div 2
d += d div numPoints
var k = 0
Expand All @@ -58,7 +58,7 @@ proc adapt(delta, numPoints: int, first: bool): int =
k += Base
result = k + (Base - TMin + 1) * d div (d + Skew)

proc encode*(prefix, s: string): string {.raises: [PunyError].} =
func encode*(prefix, s: string): string {.raises: [PunyError].} =
## Encode a string that may contain Unicode.
## Prepend `prefix` to the result
result = prefix
Expand Down Expand Up @@ -114,26 +114,26 @@ proc encode*(prefix, s: string): string {.raises: [PunyError].} =
inc d
inc n

proc encode*(s: string): string {.raises: [PunyError].} =
func encode*(s: string): string {.raises: [PunyError].} =
## Encode a string that may contain Unicode. Prefix is empty.
result = encode("", s)

proc decode*(encoded: string): string {.raises: [PunyError].} =
func decode*(encoded: string): string {.raises: [PunyError].} =
## Decode a Punycode-encoded string
var
n = InitialN
i = 0
bias = InitialBias
var d = rfind(encoded, Delimiter)
result = ""
var output: seq[Rune]

if d > 0:
# found Delimiter
for j in 0..<d:
var c = encoded[j] # char
if not c.isBasic:
raise newException(PunyError, "Encoded contains a non-basic char")
result.add(c) # add the character
output.add(Rune(c)) # add the character
inc d
else:
d = 0 # set to first index
Expand Down Expand Up @@ -161,16 +161,17 @@ proc decode*(encoded: string): string {.raises: [PunyError].} =
break
w *= Base - t
k += Base
bias = adapt(i - oldi, runeLen(result) + 1, oldi == 0)
bias = adapt(i - oldi, len(output) + 1, oldi == 0)

if i div (runeLen(result) + 1) > high(int32) - n:
if i div (len(output) + 1) > high(int32) - n:
raise newException(PunyError, "Value too large")

n += i div (runeLen(result) + 1)
i = i mod (runeLen(result) + 1)
insert(result, $Rune(n), i)
n += i div (len(output) + 1)
i = i mod (len(output) + 1)
insert(output, Rune(n), i)
inc i

result = $output

runnableExamples:
static:
Expand Down
2 changes: 1 addition & 1 deletion lib/pure/segfaults.nim
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ when defined(windows):

const
EXCEPTION_ACCESS_VIOLATION = DWORD(0xc0000005'i32)
EXCEPTION_CONTINUE_SEARCH = Long(0)
EXCEPTION_CONTINUE_SEARCH = LONG(0)

type
PEXCEPTION_RECORD = ptr object
Expand Down
5 changes: 5 additions & 0 deletions lib/pure/streams.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1194,6 +1194,11 @@ else: # after 1.3 or JS not defined

proc ssReadDataStr(s: Stream, buffer: var string, slice: Slice[int]): int =
var s = StringStream(s)
when nimvm:
discard
else:
when declared(prepareMutation):
prepareMutation(buffer) # buffer might potentially be a CoW literal with ARC
result = min(slice.b + 1 - slice.a, s.data.len - s.pos)
if result > 0:
jsOrVmBlock:
Expand Down
5 changes: 3 additions & 2 deletions lib/std/jsfetch.nim
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,9 @@ func newfetchOptions*(metod: HttpMethod; body: cstring;
keepalive: bool; redirect = frFollow; referrer = "client".cstring; integrity = "".cstring): FetchOptions =
## Constructor for `FetchOptions`.
result = FetchOptions(
body: body, mode: $mode, credentials: $credentials, cache: $cache, referrerPolicy: $referrerPolicy,
keepalive: keepalive, redirect: $redirect, referrer: referrer, integrity: integrity,
body: if metod notin {HttpHead, HttpGet}: body else: nil,
mode: cstring($mode), credentials: cstring($credentials), cache: cstring($cache), referrerPolicy: cstring($referrerPolicy),
keepalive: keepalive, redirect: cstring($redirect), referrer: referrer, integrity: integrity,
metod: (case metod
of HttpHead: "HEAD".cstring
of HttpGet: "GET".cstring
Expand Down
2 changes: 1 addition & 1 deletion lib/std/strbasics.nim
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func setSlice*(s: var string, slice: Slice[int]) =
import std/sugar

var a = "Hello, Nim!"
doassert a.dup(setSlice(7 .. 9)) == "Nim"
doAssert a.dup(setSlice(7 .. 9)) == "Nim"
doAssert a.dup(setSlice(0 .. 0)) == "H"
doAssert a.dup(setSlice(0 .. 1)) == "He"
doAssert a.dup(setSlice(0 .. 10)) == a
Expand Down
7 changes: 3 additions & 4 deletions lib/std/sysrand.nim
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,8 @@ elif defined(linux) and not defined(nimNoGetRandom) and not defined(emscripten):
const syscallHeader = """#include <unistd.h>
#include <sys/syscall.h>"""

proc syscall(
n: clong, buf: pointer, bufLen: cint, flags: cuint
): clong {.importc: "syscall", header: syscallHeader.}
proc syscall(n: clong): clong {.
importc: "syscall", varargs, header: syscallHeader.}
# When reading from the urandom source (GRND_RANDOM is not set),
# getrandom() will block until the entropy pool has been
# initialized (unless the GRND_NONBLOCK flag was specified). If a
Expand Down Expand Up @@ -211,7 +210,7 @@ elif defined(zephyr):
proc sys_csrand_get(dst: pointer, length: csize_t): cint {.importc: "sys_csrand_get", header: "<random/rand32.h>".}
# Fill the destination buffer with cryptographically secure
# random data values
#
#

proc getRandomImpl(p: pointer, size: int): int {.inline.} =
# 0 if success, -EIO if entropy reseed error
Expand Down
6 changes: 3 additions & 3 deletions lib/std/tasks.nim
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@ template checkIsolate(scratchAssignList: seq[NimNode], procParam, scratchDotExpr
# var isoTempB = isolate(literal)
# scratch.b = extract(isolateB)
let isolatedTemp = genSym(nskTemp, "isoTemp")
scratchAssignList.add newVarStmt(isolatedTemp, newCall(newidentNode("isolate"), procParam))
scratchAssignList.add newVarStmt(isolatedTemp, newCall(newIdentNode("isolate"), procParam))
scratchAssignList.add newAssignment(scratchDotExpr,
newcall(newIdentNode("extract"), isolatedTemp))
newCall(newIdentNode("extract"), isolatedTemp))

template addAllNode(assignParam: NimNode, procParam: NimNode) =
let scratchDotExpr = newDotExpr(scratchIdent, formalParams[i][0])
Expand Down Expand Up @@ -154,7 +154,7 @@ macro toTask*(e: typed{nkCall | nkInfix | nkPrefix | nkPostfix | nkCommand | nkC
error("'toTask'ed function cannot have a 'typed' or 'untyped' parameter", e)
let
seqType = nnkBracketExpr.newTree(newIdentNode("seq"), param[1])
seqCallNode = newcall("@", e[i])
seqCallNode = newCall("@", e[i])
addAllNode(seqType, seqCallNode)
else:
addAllNode(param, e[i])
Expand Down
2 changes: 1 addition & 1 deletion lib/system.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2128,7 +2128,7 @@ const
## is the minor number of Nim's version.
## Odd for devel, even for releases.

NimPatch* {.intdefine.}: int = 6
NimPatch* {.intdefine.}: int = 8
## is the patch number of Nim's version.
## Odd for devel, even for releases.

Expand Down
9 changes: 8 additions & 1 deletion lib/system/ansi_c.nim
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,9 @@ elif defined(nimBuiltinSetjmp):
proc c_builtin_setjmp(jmpb: ptr pointer): cint {.
importc: "__builtin_setjmp", nodecl.}
c_builtin_setjmp(unsafeAddr jmpb[0])

elif defined(nimRawSetjmp) and not defined(nimStdSetjmp):
when defined(windows):
when defined(windows) and not defined(vcc):
# No `_longjmp()` on Windows.
proc c_longjmp*(jmpb: C_JmpBuf, retval: cint) {.
header: "<setjmp.h>", importc: "longjmp".}
Expand All @@ -127,10 +128,16 @@ elif defined(nimRawSetjmp) and not defined(nimStdSetjmp):
# prone to stack corruption during unwinding, so we disable that by setting
# it to NULL.
# More details: https://github.com/status-im/nimbus-eth2/issues/3121
when defined(nimHasStyleChecks):
{.push styleChecks: off.}

proc c_setjmp*(jmpb: C_JmpBuf): cint =
proc c_setjmp_win(jmpb: C_JmpBuf, ctx: pointer): cint {.
header: "<setjmp.h>", importc: "_setjmp".}
c_setjmp_win(jmpb, nil)

when defined(nimHasStyleChecks):
{.pop.}
else:
proc c_longjmp*(jmpb: C_JmpBuf, retval: cint) {.
header: "<setjmp.h>", importc: "_longjmp".}
Expand Down
3 changes: 3 additions & 0 deletions lib/system/widestrs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -224,3 +224,6 @@ when defined(nimv2):

proc `$`*(s: WideCStringObj): string =
$(s.data)

proc len*(w: WideCStringObj): int {.inline.} =
len(w.data)
18 changes: 9 additions & 9 deletions lib/windows/registry.nim
Original file line number Diff line number Diff line change
Expand Up @@ -46,26 +46,26 @@ template call(f) =
proc getUnicodeValue*(path, key: string; handle: HKEY): string =
let hh = newWideCString path
let kk = newWideCString key
var bufsize: int32
var bufSize: int32
# try a couple of different flag settings:
var flags: int32 = RRF_RT_ANY
let err = regGetValue(handle, hh, kk, flags, nil, nil, addr bufsize)
let err = regGetValue(handle, hh, kk, flags, nil, nil, addr bufSize)
if err != 0:
var newHandle: HKEY
call regOpenKeyEx(handle, hh, 0, KEY_READ or KEY_WOW64_64KEY, newHandle)
call regGetValue(newHandle, nil, kk, flags, nil, nil, addr bufsize)
call regGetValue(newHandle, nil, kk, flags, nil, nil, addr bufSize)
if bufSize > 0:
var res = newWideCString(bufsize)
var res = newWideCString(bufSize)
call regGetValue(newHandle, nil, kk, flags, nil, addr res[0],
addr bufsize)
result = res $ bufsize
addr bufSize)
result = res $ bufSize
call regCloseKey(newHandle)
else:
if bufSize > 0:
var res = newWideCString(bufsize)
var res = newWideCString(bufSize)
call regGetValue(handle, hh, kk, flags, nil, addr res[0],
addr bufsize)
result = res $ bufsize
addr bufSize)
result = res $ bufSize

proc regSetValue(key: HKEY, lpSubKey, lpValueName: WideCString,
dwType: int32; lpData: WideCString; cbData: int32): int32 {.
Expand Down
2 changes: 1 addition & 1 deletion lib/windows/winlean.nim
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ proc getaddrinfo*(nodename, servname: cstring, hints: ptr AddrInfo,
res: var ptr AddrInfo): cint {.
stdcall, importc: "getaddrinfo", dynlib: ws2dll.}

proc freeaddrinfo*(ai: ptr AddrInfo) {.
proc freeAddrInfo*(ai: ptr AddrInfo) {.
stdcall, importc: "freeaddrinfo", dynlib: ws2dll.}

proc inet_ntoa*(i: InAddr): cstring {.
Expand Down
248 changes: 234 additions & 14 deletions nimsuggest/nimsuggest.nim
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
# distribution, for details about the copyright.
#

import compiler/renderer
import strformat
import tables
import std/sha1
import times

## Nimsuggest is a tool that helps to give editors IDE like capabilities.

when not defined(nimcore):
Expand All @@ -22,6 +28,7 @@ import compiler / [options, commands, modules, sem,
idents, modulegraphs, prefixmatches, lineinfos, cmdlinehelper,
pathutils]


when defined(windows):
import winlean
else:
Expand All @@ -43,6 +50,8 @@ Options:
--debug enable debug output
--log enable verbose logging to nimsuggest.log file
--v1 use version 1 of the protocol; for backwards compatibility
--v2 use version 2(default) of the protocol
--v3 use version 3 of the protocol
--refresh perform automatic refreshes to keep the analysis precise
--maxresults:N limit the number of suggestions to N
--tester implies --stdin and outputs a line
Expand Down Expand Up @@ -76,6 +85,9 @@ var
requests: Channel[string]
results: Channel[Suggest]

proc executeNoHooksV3(cmd: IdeCmd, file: AbsoluteFile, dirtyfile: AbsoluteFile, line, col: int;
graph: ModuleGraph);

proc writelnToChannel(line: string) =
results.send(Suggest(section: ideMsg, doc: line))

Expand Down Expand Up @@ -137,7 +149,7 @@ proc listEpc(): SexpNode =
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", "mod"]:
for command in ["sug", "con", "def", "use", "dus", "chk", "mod", "globalSymbols", "recompile", "saved", "chkFile"]:
let
cmd = sexp(command)
methodDesc = newSList()
Expand All @@ -163,6 +175,11 @@ proc symFromInfo(graph: ModuleGraph; trackPos: TLineInfo): PSym =
proc executeNoHooks(cmd: IdeCmd, file, dirtyfile: AbsoluteFile, line, col: int;
graph: ModuleGraph) =
let conf = graph.config

if conf.suggestVersion == 3:
executeNoHooksV3(cmd, file, dirtyfile, line, col, graph)
return

myLog("cmd: " & $cmd & ", file: " & file.string &
", dirtyFile: " & dirtyfile.string &
"[" & $line & ":" & $col & "]")
Expand Down Expand Up @@ -436,6 +453,11 @@ proc execCmd(cmd: string; graph: ModuleGraph; cachedMsgs: CachedMsgs) =
of "terse": toggle optIdeTerse
of "known": conf.ideCmd = ideKnown
of "project": conf.ideCmd = ideProject
of "changed": conf.ideCmd = ideChanged
of "globalsymbols": conf.ideCmd = ideGlobalSymbols
of "chkfile": conf.ideCmd = ideChkFile
of "recompile": conf.ideCmd = ideRecompile
of "type": conf.ideCmd = ideType
else: err()
var dirtyfile = ""
var orig = ""
Expand Down Expand Up @@ -463,14 +485,23 @@ proc execCmd(cmd: string; graph: ModuleGraph; cachedMsgs: CachedMsgs) =
execute(conf.ideCmd, AbsoluteFile orig, AbsoluteFile dirtyfile, line, col, graph)
sentinel()

template benchmark(benchmarkName: string, code: untyped) =
block:
myLog "Started [" & benchmarkName & "]..."
let t0 = epochTime()
code
let elapsed = epochTime() - t0
let elapsedStr = elapsed.formatFloat(format = ffDecimal, precision = 3)
myLog "CPU Time [" & benchmarkName & "] " & elapsedStr & "s"

proc recompileFullProject(graph: ModuleGraph) =
#echo "recompiling full project"
resetSystemArtifacts(graph)
graph.vm = nil
graph.resetAllModules()
GC_fullCollect()
compileProject(graph)
#echo GC_getStatistics()
benchmark "Recompilation(clean)":
graph.resetForBackend()
graph.resetSystemArtifacts()
graph.vm = nil
graph.resetAllModules()
GC_fullCollect()
graph.compileProject()

proc mainThread(graph: ModuleGraph) =
let conf = graph.config
Expand Down Expand Up @@ -499,7 +530,7 @@ proc mainThread(graph: ModuleGraph) =
else:
os.sleep 250
idle += 1
if idle == 20 and gRefresh:
if idle == 20 and gRefresh and conf.suggestVersion != 3:
# we use some nimsuggest activity to enable a lazy recompile:
conf.ideCmd = ideChk
conf.writelnHook = proc (s: string) = discard
Expand Down Expand Up @@ -527,12 +558,18 @@ proc mainCommand(graph: ModuleGraph) =

conf.setErrorMaxHighMaybe # honor --errorMax even if it may not make sense here
# do not print errors, but log them
conf.writelnHook = myLog
conf.structuredErrorHook = nil
conf.writelnHook = proc (msg: string) = discard

if graph.config.suggestVersion == 3:
graph.config.structuredErrorHook = proc (conf: ConfigRef; info: TLineInfo; msg: string; sev: Severity) =
let suggest = Suggest(section: ideChk, filePath: toFullPath(conf, info),
line: toLinenumber(info), column: toColumn(info), doc: msg, forth: $sev)
graph.suggestErrors.mgetOrPut(info.fileIndex, @[]).add suggest

# compile the project before showing any input so that we already
# can answer questions right away:
compileProject(graph)
benchmark "Initial compilation":
compileProject(graph)

open(requests)
open(results)
Expand Down Expand Up @@ -584,8 +621,9 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string; conf: ConfigRef) =
gMode = mepc
conf.verbosity = 0 # Port number gotta be first.
of "debug": incl(conf.globalOptions, optIdeDebug)
of "v2": conf.suggestVersion = 0
of "v1": conf.suggestVersion = 1
of "v2": conf.suggestVersion = 0
of "v3": conf.suggestVersion = 3
of "tester":
gMode = mstdin
gEmitEof = true
Expand Down Expand Up @@ -647,6 +685,187 @@ proc handleCmdLine(cache: IdentCache; conf: ConfigRef) =
if self.loadConfigsAndProcessCmdLine(cache, conf, graph):
mainCommand(graph)

# v3 start

proc recompilePartially(graph: ModuleGraph, projectFileIdx = InvalidFileIdx) =
if projectFileIdx == InvalidFileIdx:
myLog "Recompiling partially from root"
else:
myLog fmt "Recompiling partially starting from {graph.getModule(projectFileIdx)}"

# inst caches are breaking incremental compilation when the cache caches stuff
# from dirty buffer
# TODO: investigate more efficient way to achieve the same
# graph.typeInstCache.clear()
# graph.procInstCache.clear()

GC_fullCollect()

try:
benchmark "Recompilation":
graph.compileProject(projectFileIdx)
except Exception as e:
myLog fmt "Failed to recompile partially with the following error:\n {e.msg} \n\n {e.getStackTrace()}"
try:
graph.recompileFullProject()
except Exception as e:
myLog fmt "Failed clean recompilation:\n {e.msg} \n\n {e.getStackTrace()}"

proc findSymData(graph: ModuleGraph, file: AbsoluteFile; line, col: int):
ref SymInfoPair =
let
fileIdx = fileInfoIdx(graph.config, file)
trackPos = newLineInfo(fileIdx, line, col)
for s in graph.fileSymbols(fileIdx):
if isTracked(s.info, trackPos, s.sym.name.s.len):
new(result)
result[] = s
break

proc markDirtyIfNeeded(graph: ModuleGraph, file: string, originalFileIdx: FileIndex) =
let sha = $sha1.secureHashFile(file)
if graph.config.m.fileInfos[originalFileIdx.int32].hash != sha or graph.config.ideCmd == ideSug:
myLog fmt "{file} changed compared to last compilation"
graph.markDirty originalFileIdx
graph.markClientsDirty originalFileIdx
else:
myLog fmt "No changes in file {file} compared to last compilation"

proc suggestResult(graph: ModuleGraph, sym: PSym, info: TLineInfo, defaultSection = ideNone) =
let section = if defaultSection != ideNone:
defaultSection
elif sym.info.exactEquals(info):
ideDef
else:
ideUse
let suggest = symToSuggest(graph, sym, isLocal=false, section,
info, 100, PrefixMatch.None, false, 0)
suggestResult(graph.config, suggest)

const
# kinds for ideOutline and ideGlobalSymbols
searchableSymKinds = {skField, skEnumField, skIterator, skMethod, skFunc, skProc, skConverter, skTemplate}

proc executeNoHooksV3(cmd: IdeCmd, file: AbsoluteFile, dirtyfile: AbsoluteFile, line, col: int;
graph: ModuleGraph) =
let conf = graph.config
conf.writelnHook = proc (s: string) = discard
conf.structuredErrorHook = proc (conf: ConfigRef; info: TLineInfo;
msg: string; sev: Severity) =
let suggest = Suggest(section: ideChk, filePath: toFullPath(conf, info),
line: toLinenumber(info), column: toColumn(info), doc: msg, forth: $sev)
graph.suggestErrors.mgetOrPut(info.fileIndex, @[]).add suggest

conf.ideCmd = cmd

myLog fmt "cmd: {cmd}, file: {file}[{line}:{col}], dirtyFile: {dirtyfile}"

var fileIndex: FileIndex

if not (cmd in {ideRecompile, ideGlobalSymbols}):
if not fileInfoKnown(conf, file):
myLog fmt "{file} is unknown, returning no results"
return

fileIndex = fileInfoIdx(conf, file)
msgs.setDirtyFile(
conf,
fileIndex,
if dirtyfile.isEmpty: AbsoluteFile"" else: dirtyfile)

if not dirtyfile.isEmpty:
graph.markDirtyIfNeeded(dirtyFile.string, fileInfoIdx(conf, file))

# these commands require fully compiled project
if cmd in {ideUse, ideDus, ideGlobalSymbols, ideChk} and graph.needsCompilation():
graph.recompilePartially()
# when doing incremental build for the project root we should make sure that
# everything is unmarked as no longer beeing dirty in case there is no
# longer reference to a particular module. E. g. A depends on B, B is marked
# as dirty and A loses B import.
graph.unmarkAllDirty()

# these commands require partially compiled project
elif cmd in {ideSug, ideOutline, ideHighlight, ideDef, ideChkFile, ideType} and
(graph.needsCompilation(fileIndex) or cmd == ideSug):
# for ideSug use v2 implementation
if cmd == ideSug:
conf.m.trackPos = newLineInfo(fileIndex, line, col)
conf.m.trackPosAttached = false
else:
conf.m.trackPos = default(TLineInfo)

graph.recompilePartially(fileIndex)

case cmd
of ideDef:
let s = graph.findSymData(file, line, col)
if not s.isNil:
graph.suggestResult(s.sym, s.sym.info)
of ideType:
let s = graph.findSymData(file, line, col)
if not s.isNil:
let typeSym = s.sym.typ.sym
if typeSym != nil:
graph.suggestResult(typeSym, typeSym.info, ideType)
elif s.sym.typ.len != 0:
let genericType = s.sym.typ[0].sym
graph.suggestResult(genericType, genericType.info, ideType)
of ideUse, ideDus:
let symbol = graph.findSymData(file, line, col)
if not symbol.isNil:
for s in graph.suggestSymbolsIter:
if s.sym == symbol.sym:
graph.suggestResult(s.sym, s.info)
of ideHighlight:
let sym = graph.findSymData(file, line, col)
if not sym.isNil:
let usages = graph.fileSymbols(fileIndex).filterIt(it.sym == sym.sym)
myLog fmt "Found {usages.len} usages in {file.string}"
for s in usages:
graph.suggestResult(s.sym, s.info)
of ideRecompile:
graph.recompileFullProject()
of ideChanged:
graph.markDirtyIfNeeded(file.string, fileIndex)
of ideSug:
# ideSug performs partial build of the file, thus mark it dirty for the
# future calls.
graph.markDirtyIfNeeded(file.string, fileIndex)
of ideOutline:
let
module = graph.getModule fileIndex
symbols = graph.fileSymbols(fileIndex)
.filterIt(it.sym.info.exactEquals(it.info) and
(it.sym.owner == module or
it.sym.kind in searchableSymKinds))

for s in symbols:
graph.suggestResult(s.sym, s.info, ideOutline)
of ideChk:
myLog fmt "Reporting errors for {graph.suggestErrors.len} file(s)"
for sug in graph.suggestErrorsIter:
suggestResult(graph.config, sug)
of ideChkFile:
let errors = graph.suggestErrors.getOrDefault(fileIndex, @[])
myLog fmt "Reporting {errors.len} error(s) for {file.string}"
for error in errors:
suggestResult(graph.config, error)
of ideGlobalSymbols:
var counter = 0
for s in graph.suggestSymbolsIter:
if (sfGlobal in s.sym.flags or s.sym.kind in searchableSymKinds) and
s.sym.info == s.info:
if contains(s.sym.name.s, file.string):
inc counter
graph.suggestResult(s.sym, s.info)
# stop after first 100 results
if counter > 100:
break
else:
myLog fmt "Discarding {cmd}"

# v3 end
when isMainModule:
handleCmdLine(newIdentCache(), newConfigRef())
else:
Expand Down Expand Up @@ -726,8 +945,9 @@ else:
if self.loadConfigsAndProcessCmdLine(cache, conf, graph):
mockCommand(graph)
if gLogging:
log("Search paths:")
for it in conf.searchPaths:
log(it.string)
log(" " & it.string)

retval.doStopCompile = proc (): bool = false
return NimSuggest(graph: retval, idle: 0, cachedMsgs: @[])
Expand Down
7 changes: 5 additions & 2 deletions nimsuggest/tester.nim
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,10 @@ proc runEpcTest(filename: string): int =
for cmd in s.startup:
if not runCmd(cmd, s.dest):
quit "invalid command: " & cmd
let epccmd = s.cmd.replace("--tester", "--epc --v2 --log")
let epccmd = if s.cmd.contains("--v3"):
s.cmd.replace("--tester", "--epc --log")
else:
s.cmd.replace("--tester", "--epc --v2 --log")
let cl = parseCmdLine(epccmd)
var p = startProcess(command=cl[0], args=cl[1 .. ^1],
options={poStdErrToStdOut, poUsePath,
Expand All @@ -279,7 +282,7 @@ proc runEpcTest(filename: string): int =
socket.sendEpcStr(req)
let sx = parseSexp(socket.recvEpc())
if not req.startsWith("mod "):
let answer = sexpToAnswer(sx)
let answer = if sx[2].kind == SNil: "" else: sexpToAnswer(sx)
doReport(filename, answer, resp, report)

socket.sendEpcStr "return arg"
Expand Down
31 changes: 31 additions & 0 deletions nimsuggest/tests/tv3.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# tests v3

type
Foo* = ref object of RootObj
bar*: string

proc test(f: Foo) =
echo f.ba#[!]#r

#[!]#

discard """
$nimsuggest --v3 --tester $file
>use $1
def skField tv3.Foo.bar string $file 5 4 "" 100
use skField tv3.Foo.bar string $file 8 9 "" 100
>def $1
def skField tv3.Foo.bar string $file 5 4 "" 100
>outline $1
outline skType tv3.Foo Foo $file 4 2 "" 100
outline skField tv3.Foo.bar string $file 5 4 "" 100
outline skProc tv3.test proc (f: Foo){.gcsafe, locks: 0.} $file 7 5 "" 100
>sug $1
sug skField bar string $file 5 4 "" 100 Prefix
>globalSymbols test
def skProc tv3.test proc (f: Foo){.gcsafe, locks: 0.} $file 7 5 "" 100
>globalSymbols Foo
def skType tv3.Foo Foo $file 4 2 "" 100
>def $2
>use $2
"""
9 changes: 9 additions & 0 deletions nimsuggest/tests/tv3_definition.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

let foo = 30
let bar = foo + fo#[!]#o + foo

discard """
$nimsuggest --v3 --tester $file
>def $1
def skLet tv3_definition.foo int $file 2 4 "" 100
"""
7 changes: 7 additions & 0 deletions nimsuggest/tests/tv3_import.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import tv#[!]#3

discard """
$nimsuggest --v3 --tester $file
>def $1
def skModule tv3 */tv3.nim 1 0 "" 100
"""
32 changes: 32 additions & 0 deletions nimsuggest/tests/tv3_typeDefinition.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# tests v3

type
Foo* = ref object of RootObj
bar*: string

proc test(ff: Foo) =
echo f#[!]#f.bar

type
Fo#[!]#o2* = ref object of RootObj

type
FooGeneric[T] = ref object of RootObj
bar*: T

let fooGeneric = FooGeneric[string]()
echo fo#[!]#oGeneric.bar

# bad type
echo unde#[!]#fined

discard """
$nimsuggest --v3 --tester $file
>type $1
type skType tv3_typeDefinition.Foo Foo $file 4 2 "" 100
>type $2
type skType tv3_typeDefinition.Foo2 Foo2 $file 11 2 "" 100
>type $3
type skType tv3_typeDefinition.FooGeneric FooGeneric $file 14 2 "" 100
>type $4
"""
12 changes: 6 additions & 6 deletions testament/categories.nim
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ proc testNimblePackages(r: var TResults; cat: Category; packageFilter: string) =
if pkg.allowFailure:
inc r.passed
inc r.failedButAllowed
addResult(r, test, targetC, "", cmd & "\n" & outp, reFailed, allowFailure = pkg.allowFailure)
addResult(r, test, targetC, "", "", cmd & "\n" & outp, reFailed, allowFailure = pkg.allowFailure)
continue
outp

Expand All @@ -450,21 +450,21 @@ proc testNimblePackages(r: var TResults; cat: Category; packageFilter: string) =
discard tryCommand("nimble install --depsOnly -y", maxRetries = 3)
discard tryCommand(pkg.cmd, reFailed = reBuildFailed)
inc r.passed
r.addResult(test, targetC, "", "", reSuccess, allowFailure = pkg.allowFailure)
r.addResult(test, targetC, "", "", "", reSuccess, allowFailure = pkg.allowFailure)

errors = r.total - r.passed
if errors == 0:
r.addResult(packageFileTest, targetC, "", "", reSuccess)
r.addResult(packageFileTest, targetC, "", "", "", reSuccess)
else:
r.addResult(packageFileTest, targetC, "", "", reBuildFailed)
r.addResult(packageFileTest, targetC, "", "", "", reBuildFailed)

except JsonParsingError:
errors = 1
r.addResult(packageFileTest, targetC, "", "Invalid package file", reBuildFailed)
r.addResult(packageFileTest, targetC, "", "", "Invalid package file", reBuildFailed)
raise
except ValueError:
errors = 1
r.addResult(packageFileTest, targetC, "", "Unknown package", reBuildFailed)
r.addResult(packageFileTest, targetC, "", "", "Unknown package", reBuildFailed)
raise # bug #18805
finally:
if errors == 0: removeDir(packagesDir)
Expand Down
97 changes: 50 additions & 47 deletions testament/testament.nim
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Options:
--verbose print commands (compiling and running tests)
--simulate see what tests would be run but don't run them (for debugging)
--failing only show failing/ignored tests
--targets:"c cpp js objc" run tests for specified targets (default: all)
--targets:"c cpp js objc" run tests for specified targets (default: c)
--nim:path use a particular nim executable (default: $$PATH/nim)
--directory:dir Change to directory dir before reading the tests or doing anything else.
--colors:on|off Turn messages coloring on|off.
Expand Down Expand Up @@ -258,18 +258,23 @@ Tests failed and allowed to fail: $3 / $1 <br />
Tests skipped: $4 / $1 <br />
""" % [$x.total, $x.passed, $x.failedButAllowed, $x.skipped]

proc addResult(r: var TResults, test: TTest, target: TTarget,
expected, given: string, successOrig: TResultEnum, allowFailure = false, givenSpec: ptr TSpec = nil) =
# instead of `ptr TSpec` we could also use `Option[TSpec]`; passing `givenSpec` makes it easier to get what we need
# instead of having to pass individual fields, or abusing existing ones like expected vs given.
# test.name is easier to find than test.name.extractFilename
# A bit hacky but simple and works with tests/testament/tshould_not_work.nim
proc testName(test: TTest, target: TTarget, extraOptions: string, allowFailure: bool): string =
var name = test.name.replace(DirSep, '/')
name.add ' ' & $target
if allowFailure:
name.add " (allowed to fail) "
if test.options.len > 0: name.add ' ' & test.options
if extraOptions.len > 0: name.add ' ' & extraOptions
name.strip()

proc addResult(r: var TResults, test: TTest, target: TTarget,
extraOptions, expected, given: string, successOrig: TResultEnum,
allowFailure = false, givenSpec: ptr TSpec = nil) =
# instead of `ptr TSpec` we could also use `Option[TSpec]`; passing `givenSpec` makes it easier to get what we need
# instead of having to pass individual fields, or abusing existing ones like expected vs given.
# test.name is easier to find than test.name.extractFilename
# A bit hacky but simple and works with tests/testament/tshould_not_work.nim
let name = testName(test, target, extraOptions, allowFailure)
let duration = epochTime() - test.startTime
let success = if test.spec.timeout > 0.0 and duration > test.spec.timeout: reTimeout
else: successOrig
Expand Down Expand Up @@ -333,7 +338,8 @@ proc addResult(r: var TResults, test: TTest, target: TTarget,
discard waitForExit(p)
close(p)

proc checkForInlineErrors(r: var TResults, expected, given: TSpec, test: TTest, target: TTarget) =
proc checkForInlineErrors(r: var TResults, expected, given: TSpec, test: TTest,
target: TTarget, extraOptions: string) =
let pegLine = peg"{[^(]*} '(' {\d+} ', ' {\d+} ') ' {[^:]*} ':' \s* {.*}"
var covered = initIntSet()
for line in splitLines(given.nimout):
Expand Down Expand Up @@ -367,10 +373,10 @@ proc checkForInlineErrors(r: var TResults, expected, given: TSpec, test: TTest,
e.add ": "
e.add expected.inlineErrors[j].msg

r.addResult(test, target, e, given.nimout, reMsgsDiffer)
r.addResult(test, target, extraOptions, e, given.nimout, reMsgsDiffer)
break coverCheck

r.addResult(test, target, "", given.msg, reSuccess)
r.addResult(test, target, extraOptions, "", given.msg, reSuccess)
inc(r.passed)

proc nimoutCheck(expected, given: TSpec): bool =
Expand All @@ -381,22 +387,23 @@ proc nimoutCheck(expected, given: TSpec): bool =
elif expected.nimout.len > 0 and not greedyOrderedSubsetLines(expected.nimout, given.nimout):
result = false

proc cmpMsgs(r: var TResults, expected, given: TSpec, test: TTest, target: TTarget) =
proc cmpMsgs(r: var TResults, expected, given: TSpec, test: TTest,
target: TTarget, extraOptions: string) =
if expected.inlineErrors.len > 0:
checkForInlineErrors(r, expected, given, test, target)
checkForInlineErrors(r, expected, given, test, target, extraOptions)
elif strip(expected.msg) notin strip(given.msg):
r.addResult(test, target, expected.msg, given.msg, reMsgsDiffer)
r.addResult(test, target, extraOptions, expected.msg, given.msg, reMsgsDiffer)
elif not nimoutCheck(expected, given):
r.addResult(test, target, expected.nimout, given.nimout, reMsgsDiffer)
r.addResult(test, target, extraOptions, expected.nimout, given.nimout, reMsgsDiffer)
elif extractFilename(expected.file) != extractFilename(given.file) and
"internal error:" notin expected.msg:
r.addResult(test, target, expected.file, given.file, reFilesDiffer)
r.addResult(test, target, extraOptions, expected.file, given.file, reFilesDiffer)
elif expected.line != given.line and expected.line != 0 or
expected.column != given.column and expected.column != 0:
r.addResult(test, target, $expected.line & ':' & $expected.column,
r.addResult(test, target, extraOptions, $expected.line & ':' & $expected.column,
$given.line & ':' & $given.column, reLinesDiffer)
else:
r.addResult(test, target, expected.msg, given.msg, reSuccess)
r.addResult(test, target, extraOptions, expected.msg, given.msg, reSuccess)
inc(r.passed)

proc generatedFile(test: TTest, target: TTarget): string =
Expand Down Expand Up @@ -434,8 +441,8 @@ proc codegenCheck(test: TTest, target: TTarget, spec: TSpec, expectedMsg: var st
given.err = reCodeNotFound
echo getCurrentExceptionMsg()

proc compilerOutputTests(test: TTest, target: TTarget, given: var TSpec,
expected: TSpec; r: var TResults) =
proc compilerOutputTests(test: TTest, target: TTarget, extraOptions: string,
given: var TSpec, expected: TSpec; r: var TResults) =
var expectedmsg: string = ""
var givenmsg: string = ""
if given.err == reSuccess:
Expand All @@ -449,55 +456,53 @@ proc compilerOutputTests(test: TTest, target: TTarget, given: var TSpec,
else:
givenmsg = "$ " & given.cmd & '\n' & given.nimout
if given.err == reSuccess: inc(r.passed)
r.addResult(test, target, expectedmsg, givenmsg, given.err)
r.addResult(test, target, extraOptions, expectedmsg, givenmsg, given.err)

proc getTestSpecTarget(): TTarget =
if getEnv("NIM_COMPILE_TO_CPP", "false") == "true":
result = targetCpp
else:
result = targetC

proc checkDisabled(r: var TResults, test: TTest): bool =
if test.spec.err in {reDisabled, reJoined}:
# targetC is a lie, but parameter is required
r.addResult(test, targetC, "", "", test.spec.err)
inc(r.skipped)
inc(r.total)
result = false
else:
result = true

var count = 0

proc equalModuloLastNewline(a, b: string): bool =
# allow lazy output spec that omits last newline, but really those should be fixed instead
result = a == b or b.endsWith("\n") and a == b[0 ..< ^1]

proc testSpecHelper(r: var TResults, test: var TTest, expected: TSpec,
target: TTarget, nimcache: string, extraOptions = "") =
target: TTarget, extraOptions: string, nimcache: string) =
test.startTime = epochTime()
if testName(test, target, extraOptions, false) in skips:
test.spec.err = reDisabled

if test.spec.err in {reDisabled, reJoined}:
r.addResult(test, target, extraOptions, "", "", test.spec.err)
inc(r.skipped)
return

template callNimCompilerImpl(): untyped =
# xxx this used to also pass: `--stdout --hint:Path:off`, but was done inconsistently
# with other branches
callNimCompiler(expected.getCmd, test.name, test.options, nimcache, target, extraOptions)
case expected.action
of actionCompile:
var given = callNimCompilerImpl()
compilerOutputTests(test, target, given, expected, r)
compilerOutputTests(test, target, extraOptions, given, expected, r)
of actionRun:
var given = callNimCompilerImpl()
if given.err != reSuccess:
r.addResult(test, target, "", "$ " & given.cmd & '\n' & given.nimout, given.err, givenSpec = given.addr)
r.addResult(test, target, extraOptions, "", "$ " & given.cmd & '\n' & given.nimout, given.err, givenSpec = given.addr)
else:
let isJsTarget = target == targetJS
var exeFile = changeFileExt(test.name, if isJsTarget: "js" else: ExeExt)
if not fileExists(exeFile):
r.addResult(test, target, expected.output,
r.addResult(test, target, extraOptions, expected.output,
"executable not found: " & exeFile, reExeNotFound)
else:
let nodejs = if isJsTarget: findNodeJs() else: ""
if isJsTarget and nodejs == "":
r.addResult(test, target, expected.output, "nodejs binary not in PATH",
r.addResult(test, target, extraOptions, expected.output, "nodejs binary not in PATH",
reExeNotFound)
else:
var exeCmd: string
Expand Down Expand Up @@ -528,41 +533,40 @@ proc testSpecHelper(r: var TResults, test: var TTest, expected: TSpec,
else:
buf
if exitCode != expected.exitCode:
r.addResult(test, target, "exitcode: " & $expected.exitCode,
r.addResult(test, target, extraOptions, "exitcode: " & $expected.exitCode,
"exitcode: " & $exitCode & "\n\nOutput:\n" &
bufB, reExitcodesDiffer)
elif (expected.outputCheck == ocEqual and not expected.output.equalModuloLastNewline(bufB)) or
(expected.outputCheck == ocSubstr and expected.output notin bufB):
given.err = reOutputsDiffer
r.addResult(test, target, expected.output, bufB, reOutputsDiffer)
r.addResult(test, target, extraOptions, expected.output, bufB, reOutputsDiffer)
else:
compilerOutputTests(test, target, given, expected, r)
compilerOutputTests(test, target, extraOptions, given, expected, r)
of actionReject:
let given = callNimCompilerImpl()
cmpMsgs(r, expected, given, test, target)
cmpMsgs(r, expected, given, test, target, extraOptions)

proc targetHelper(r: var TResults, test: TTest, expected: TSpec, extraOptions = "") =
proc targetHelper(r: var TResults, test: TTest, expected: TSpec, extraOptions: string) =
for target in expected.targets:
inc(r.total)
if target notin gTargets:
r.addResult(test, target, "", "", reDisabled)
r.addResult(test, target, extraOptions, "", "", reDisabled)
inc(r.skipped)
elif simulate:
inc count
echo "testSpec count: ", count, " expected: ", expected
else:
let nimcache = nimcacheDir(test.name, test.options, target)
var testClone = test
testSpecHelper(r, testClone, expected, target, nimcache, extraOptions)
testSpecHelper(r, testClone, expected, target, extraOptions, nimcache)

proc testSpec(r: var TResults, test: TTest, targets: set[TTarget] = {}) =
var expected = test.spec
if expected.parseErrors.len > 0:
# targetC is a lie, but a parameter is required
r.addResult(test, targetC, "", expected.parseErrors, reInvalidSpec)
r.addResult(test, targetC, "", "", expected.parseErrors, reInvalidSpec)
inc(r.total)
return
if not checkDisabled(r, test): return

expected.targets.incl targets
# still no target specified at all
Expand All @@ -572,14 +576,13 @@ proc testSpec(r: var TResults, test: TTest, targets: set[TTarget] = {}) =
for m in test.spec.matrix:
targetHelper(r, test, expected, m)
else:
targetHelper(r, test, expected)
targetHelper(r, test, expected, "")

proc testSpecWithNimcache(r: var TResults, test: TTest; nimcache: string) {.used.} =
if not checkDisabled(r, test): return
for target in test.spec.targets:
inc(r.total)
var testClone = test
testSpecHelper(r, testClone, test.spec, target, nimcache)
testSpecHelper(r, testClone, test.spec, target, "", nimcache)

proc makeTest(test, options: string, cat: Category): TTest =
result.cat = cat
Expand Down
13 changes: 13 additions & 0 deletions tests/arc/t19862.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
discard """
matrix: "--gc:refc; --gc:arc"
"""

# bug #19862
type NewString = object

proc len(s: NewString): int = 10

converter toNewString(x: WideCStringObj): NewString = discard

let w = newWideCString("test")
doAssert len(w) == 4
13 changes: 13 additions & 0 deletions tests/arc/tarc_orc.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
discard """
targets: "c cpp"
matrix: "--mm:arc; --mm:orc"
"""

Expand All @@ -20,3 +21,15 @@ block:

let keys = initKeyPair()
doAssert keys.public[0] == 88


template minIndexByIt: untyped =
var other = 3
other

proc bug20303() =
var hlibs = @["hello", "world", "how", "are", "you"]
let res = hlibs[minIndexByIt()]
doAssert res == "are"

bug20303()
45 changes: 45 additions & 0 deletions tests/arc/tcursorloop.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
discard """
cmd: '''nim c --gc:arc --expandArc:traverse --hint:Performance:off $file'''
nimout: '''
--expandArc: traverse
var
it
jt_cursor
try:
`=copy`(it, root)
block :tmp:
while (
not (it == nil)):
if true:
echo [it.s]
`=copy`(it, it.ri)
jt_cursor = root
if (
not (jt_cursor == nil)):
echo [jt_cursor.s]
jt_cursor = jt_cursor.ri
finally:
`=destroy`(it)
-- end of expandArc ------------------------
'''
"""

type
Node = ref object
le, ri: Node
s: string

proc traverse(root: Node) =
var it = root
while it != nil:
if true:
echo it.s
it = it.ri

var jt = root
if jt != nil:
echo jt.s
jt = jt.ri

traverse(nil)
4 changes: 2 additions & 2 deletions tests/arc/tmovebug.nim
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ when false:

# bug #13456

iterator combinations[T](s: openarray[T], k: int): seq[T] =
iterator combinations[T](s: openArray[T], k: int): seq[T] =
let n = len(s)
assert k >= 0 and k <= n
var pos = newSeq[int](k)
Expand Down Expand Up @@ -455,7 +455,7 @@ initFoo7(2)


# bug #14902
iterator zip[T](s: openarray[T]): (T, T) =
iterator zip[T](s: openArray[T]): (T, T) =
var i = 0
while i < 10:
yield (s[i mod 2], s[i mod 2 + 1])
Expand Down
4 changes: 2 additions & 2 deletions tests/arc/tmovebugcopy.nim
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ when false:

# bug #13456

iterator combinations[T](s: openarray[T], k: int): seq[T] =
iterator combinations[T](s: openArray[T], k: int): seq[T] =
let n = len(s)
assert k >= 0 and k <= n
var pos = newSeq[int](k)
Expand Down Expand Up @@ -416,7 +416,7 @@ initFoo7(2)


# bug #14902
iterator zip[T](s: openarray[T]): (T, T) =
iterator zip[T](s: openArray[T]): (T, T) =
var i = 0
while i < 10:
yield (s[i mod 2], s[i mod 2 + 1])
Expand Down
2 changes: 1 addition & 1 deletion tests/array/tarray.nim
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ block tarray:
arr: TMyarray


proc sum(a: openarray[int]): int =
proc sum(a: openArray[int]): int =
result = 0
var i = 0
while i < len(a):
Expand Down
4 changes: 2 additions & 2 deletions tests/async/tioselectors.nim
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,8 @@ when not defined(windows):
events: set[Event]

proc vnode_test(): bool =
proc validate(test: openarray[ReadyKey],
check: openarray[valType]): bool =
proc validate(test: openArray[ReadyKey],
check: openArray[valType]): bool =
result = false
if len(test) == len(check):
for checkItem in check:
Expand Down
11 changes: 11 additions & 0 deletions tests/casestmt/tcasestmt.nim
Original file line number Diff line number Diff line change
Expand Up @@ -287,3 +287,14 @@ doAssert(foo2("Y", "a2") == 0)
doAssert(foo2("Y", "2a") == 2)
doAssert(foo2("N", "a3") == 3)
doAssert(foo2("z", "2") == 0)


# bug #20031
proc main(a: uint64) =
case a
else:
discard

static:
main(10)
main(10)
25 changes: 25 additions & 0 deletions tests/ccgbugs/tderefblock.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
discard """
cmd: "nim c -d:release -d:danger $file"
matrix: ";--gc:orc"
output: "42"
"""

# bug #20107

type Foo = object
a, b, c, d: uint64

proc c(i: uint64): Foo =
Foo(a: i, b: i, c: i, d: i)

func x(f: Foo): lent Foo {.inline.} =
f

proc m() =
let f = block:
let i = c(42)
x(i)

echo $f.a

m()
2 changes: 1 addition & 1 deletion tests/ccgbugs/tforward_decl_only.nim
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
discard """
ccodecheck: "\\i !@('struct tyObject_MyRefObject'[0-z]+' {')"
ccodecheck: "\\i !@('mymoduleInit')"
ccodecheck: "\\i @('mymoduleDatInit')"
ccodecheck: "\\i @('atmmymoduledotnim_DatInit000')"
output: "hello"
"""

Expand Down
4 changes: 2 additions & 2 deletions tests/closure/tclosure.nim
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ joinable: false


block tclosure:
proc map(n: var openarray[int], fn: proc (x: int): int {.closure}) =
proc map(n: var openArray[int], fn: proc (x: int): int {.closure}) =
for i in 0..n.len-1: n[i] = fn(n[i])

proc each(n: openarray[int], fn: proc(x: int) {.closure.}) =
proc each(n: openArray[int], fn: proc(x: int) {.closure.}) =
for i in 0..n.len-1:
fn(n[i])

Expand Down
2 changes: 1 addition & 1 deletion tests/compiles/trecursive_generic_in_compiles.nim
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ proc `==`*[T](xs, ys: List[T]): bool =

proc asList*[T](xs: varargs[T]): List[T] =
## Creates list from varargs
proc initListImpl(i: int, xs: openarray[T]): List[T] =
proc initListImpl(i: int, xs: openArray[T]): List[T] =
if i > high(xs):
Nil[T]()
else:
Expand Down
8 changes: 4 additions & 4 deletions tests/concepts/tconcepts_issues.nim
Original file line number Diff line number Diff line change
Expand Up @@ -324,15 +324,15 @@ block t6691:
block t6782:
type
Reader = concept c
c.read(openarray[byte], int, int) is int
c.read(openArray[byte], int, int) is int
Rdr = concept c
c.rd(openarray[byte], int, int) is int
c.rd(openArray[byte], int, int) is int

type TestFile = object

proc read(r: TestFile, dest: openarray[byte], offset: int, limit: int): int =
proc read(r: TestFile, dest: openArray[byte], offset: int, limit: int): int =
result = 0
proc rd(r: TestFile, dest: openarray[byte], offset: int, limit: int): int =
proc rd(r: TestFile, dest: openArray[byte], offset: int, limit: int): int =
result = 0

doAssert TestFile is Reader
Expand Down
2 changes: 2 additions & 0 deletions tests/config.nims
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,5 @@ switch("define", "nimPreviewFloatRoundtrip")
switch("define", "nimPreviewDotLikeOps")
switch("define", "nimPreviewJsonutilsHoleyEnum")
switch("define", "nimPreviewHashRef")
when defined(windows):
switch("tlsEmulation", "off")
2 changes: 1 addition & 1 deletion tests/converter/tconverter_with_varargs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type
converter to_py*(i: int) : PPyRef = nil

when false:
proc to_tuple*(vals: openarray[PPyRef]): PPyRef =
proc to_tuple*(vals: openArray[PPyRef]): PPyRef =
discard

proc abc(args: varargs[PPyRef]) =
Expand Down
8 changes: 4 additions & 4 deletions tests/cpp/tcovariancerules.nim
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,16 @@ proc wantsCovariantSeq2(s: seq[AnimalRef]) =
proc wantsCovariantSeq3(s: seq[RefAlias[Animal]]) =
for a in s: echo a.x

proc wantsCovariantOpenArray(s: openarray[ref Animal]) =
proc wantsCovariantOpenArray(s: openArray[ref Animal]) =
for a in s: echo a.x

proc modifiesCovariantOpenArray(s: var openarray[ref Animal]) =
proc modifiesCovariantOpenArray(s: var openArray[ref Animal]) =
for a in s: echo a.x

proc modifiesDerivedOpenArray(s: var openarray[ref Dog]) =
proc modifiesDerivedOpenArray(s: var openArray[ref Dog]) =
for a in s: echo a.x

proc wantsNonCovariantOpenArray(s: openarray[Animal]) =
proc wantsNonCovariantOpenArray(s: openArray[Animal]) =
for a in s: echo a.x

proc wantsCovariantArray(s: array[2, ref Animal]) =
Expand Down
2 changes: 1 addition & 1 deletion tests/destructor/tmove_objconstr.nim
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ proc myfuncLoop(x: int): MySeqNonCopyable =
discard myfuncLoop(3)

#------------------------------------------------------------
# Move into table via openarray
# Move into table via openArray
#------------------------------------------------------------

type
Expand Down
2 changes: 1 addition & 1 deletion tests/errmsgs/t17460.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ discard """
errormsg: "wrong number of variables"
"""

iterator xclusters*[T](a: openarray[T]; s: static[int]): array[s, T] {.inline.} =
iterator xclusters*[T](a: openArray[T]; s: static[int]): array[s, T] {.inline.} =
var result: array[s, T] # iterators have no default result variable
var i = 0
while i < len(a):
Expand Down
2 changes: 1 addition & 1 deletion tests/errmsgs/tproper_stacktrace.nim
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import strscans, strutils
proc raiseTestException*() =
raise newException(Exception, "test")

proc matchStackTrace(actualEntries: openarray[StackTraceEntry], expected: string) =
proc matchStackTrace(actualEntries: openArray[StackTraceEntry], expected: string) =
var expectedEntries = newSeq[StackTraceEntry]()
var i = 0

Expand Down
4 changes: 2 additions & 2 deletions tests/errmsgs/tsigmatch.nim
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,12 @@ block:
echo foo(fun)

block:
# bug #10285 Function signature don't match when inside seq/array/openarray
# bug #10285 Function signature don't match when inside seq/array/openArray
# Note: the error message now shows `closure` which helps debugging the issue
# out why it doesn't match
proc takesFunc(f: proc (x: int) {.gcsafe, locks: 0.}) =
echo "takes single Func"
proc takesFuncs(fs: openarray[proc (x: int) {.gcsafe, locks: 0.}]) =
proc takesFuncs(fs: openArray[proc (x: int) {.gcsafe, locks: 0.}]) =
echo "takes multiple Func"
takesFunc(proc (x: int) {.gcsafe, locks: 0.} = echo x) # works
takesFuncs([proc (x: int) {.gcsafe, locks: 0.} = echo x]) # fails
Expand Down
2 changes: 1 addition & 1 deletion tests/generics/tgenerics_issues.nim
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ block t7854:


block t5864:
proc defaultStatic(s: openarray, N: static[int] = 1): int = N
proc defaultStatic(s: openArray, N: static[int] = 1): int = N
proc defaultGeneric[T](a: T = 2): int = a

let a = [1, 2, 3, 4].defaultStatic()
Expand Down
4 changes: 2 additions & 2 deletions tests/generics/tgenerics_various.nim
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,8 @@ block tvarargs_vs_generics:
echo "direct"
proc withDirectType[T](arg: T) =
echo "generic"
proc withOpenArray(args: openarray[string]) =
echo "openarray"
proc withOpenArray(args: openArray[string]) =
echo "openArray"
proc withOpenArray[T](arg: T) =
echo "generic"
proc withVarargs(args: varargs[string]) =
Expand Down
2 changes: 1 addition & 1 deletion tests/iter/titer13.nim
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ block:
echo a

block t5859:
proc flatIterator[T](s: openarray[T]): auto {.noSideEffect.}=
proc flatIterator[T](s: openArray[T]): auto {.noSideEffect.}=
result = iterator(): auto =
when (T is not seq|array):
for item in s:
Expand Down
80 changes: 78 additions & 2 deletions tests/iter/titer_issues.nim
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ end
9018
@[1, 2]
@[1, 2, 3]
nested finally
outer finally
nested finally
outer finally
nested finally
outer finally
nested finally
outer finally
'''
"""

Expand Down Expand Up @@ -135,7 +143,7 @@ block t3837_chained:


block t3221_complex:
iterator permutations[T](ys: openarray[T]): seq[T] =
iterator permutations[T](ys: openArray[T]): seq[T] =
var
d = 1
c = newSeq[int](ys.len)
Expand Down Expand Up @@ -228,7 +236,7 @@ block t2023_objiter:

block:
# bug #13739
iterator myIter(arg: openarray[int]): int =
iterator myIter(arg: openArray[int]): int =
var tmp = 0
let len = arg.len
while tmp < len:
Expand Down Expand Up @@ -274,3 +282,71 @@ iterator cc() {.closure.} =
break

var a2 = cc


block:
# bug #19911 (return in nested try)

# try yield -> try
iterator p1: int {.closure.} =
try:
yield 0
try:
return
finally:
echo "nested finally"
echo "shouldn't run"
finally:
echo "outer finally"
echo "shouldn't run"

for _ in p1():
discard

# try -> try yield
iterator p2: int {.closure.} =
try:
try:
yield 0
return
finally:
echo "nested finally"
echo "shouldn't run"
finally:
echo "outer finally"
echo "shouldn't run"

for _ in p2():
discard

# try yield -> try yield
iterator p3: int {.closure.} =
try:
yield 0
try:
yield 0
return
finally:
echo "nested finally"
echo "shouldn't run"
finally:
echo "outer finally"
echo "shouldn't run"

for _ in p3():
discard

# try -> try
iterator p4: int {.closure.} =
try:
try:
return
finally:
echo "nested finally"
echo "shouldn't run"
finally:
echo "outer finally"
echo "shouldn't run"

for _ in p4():
discard
2 changes: 1 addition & 1 deletion tests/iter/tmoditer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ proc `=copy`(dst: var NonCopyable, src: NonCopyable) {.error.}
proc `=sink`(dst: var NonCopyable, src: NonCopyable) =
dst.x = src.x

iterator lentItems[T](a: openarray[T]): lent T =
iterator lentItems[T](a: openArray[T]): lent T =
for i in 0..a.high:
yield a[i]

Expand Down
2 changes: 1 addition & 1 deletion tests/iter/tpermutations.nim
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ perm: 6778800.0 det: 0.0

import sequtils, sugar

iterator permutations*[T](ys: openarray[T]): tuple[perm: seq[T], sign: int] =
iterator permutations*[T](ys: openArray[T]): tuple[perm: seq[T], sign: int] =
var
d = 1
c = newSeq[int](ys.len)
Expand Down
8 changes: 8 additions & 0 deletions tests/iter/tyieldintry.nim
Original file line number Diff line number Diff line change
Expand Up @@ -495,3 +495,11 @@ block: #17849 - yield in case subject
yield 5

test(it, 1, 2, 13, 5)

block: # void iterator
iterator it() {.closure.} =
try:
yield
except:
discard
var a = it
4 changes: 2 additions & 2 deletions tests/js/t9410.nim
Original file line number Diff line number Diff line change
Expand Up @@ -447,10 +447,10 @@ template tests =
doAssert seqOfSeqs == @[@[10, 2], @[30, 4]]

when false:
block: # openarray
block: # openArray
# Error: internal error: genAddr: nkStmtListExpr
var calls = 0
proc getvarint(x: var openarray[int]): var int =
proc getvarint(x: var openArray[int]): var int =
calls += 1
if true:
x[1]
Expand Down
2 changes: 1 addition & 1 deletion tests/js/tbasics.nim
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ for x in someGlobal: doAssert(x == 0)
proc tdefault =
var x = default(int)
doAssert(x == 0)
proc inner(v: openarray[string]) =
proc inner(v: openArray[string]) =
doAssert(v.len == 0)

inner(default(seq[string]))
Expand Down
4 changes: 2 additions & 2 deletions tests/js/tbyvar.nim
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ proc main =

main()

# Test: pass var seq to var openarray
# Test: pass var seq to var openArray
var s = @[2, 1]
proc foo(a: var openarray[int]) = a[0] = 123
proc foo(a: var openArray[int]) = a[0] = 123

proc bar(s: var seq[int], a: int) =
doAssert(a == 5)
Expand Down
2 changes: 1 addition & 1 deletion tests/lent/tbasic_lent_check.nim
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ template main2 = # bug #15958
p[] = 20.0
doAssert byLent(p)[] == 20.0

proc byLent2[T](a: openarray[T]): lent T = a[0]
proc byLent2[T](a: openArray[T]): lent T = a[0]
doAssert byLent2(a) == 11
doAssert sameAddress(byLent2(a), a[0])
doAssert byLent2(b) == 21
Expand Down
28 changes: 28 additions & 0 deletions tests/macros/t20067.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
discard """
output: '''
b.defaultVal = foo
$c.defaultVal = bar
'''
"""

import macros

# #18976

macro getString(identifier): string =
result = newLit($identifier)
doAssert getString(abc) == "abc"
doAssert getString(`a b c`) == "abc"

# #20067

template defaultVal*(value : typed) {.pragma.}

type A = ref object
b {.defaultVal: "foo".}: string
`$c` {.defaultVal: "bar".}: string

let a = A(b: "a", `$c`: "b")

echo "b.defaultVal = " & a.b.getCustomPragmaVal(defaultVal)
echo "$c.defaultVal = " & a.`$c`.getCustomPragmaVal(defaultVal)
2 changes: 1 addition & 1 deletion tests/magics/tmagics.nim
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ block tlowhigh:
for i in low(a) .. high(a):
a[i] = 0

proc sum(a: openarray[int]): int =
proc sum(a: openArray[int]): int =
result = 0
for i in low(a)..high(a):
inc(result, a[i])
Expand Down
2 changes: 1 addition & 1 deletion tests/manyloc/named_argument_bug/tri_engine/gfx/gl/gl.nim
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ else:
const
glRealType* = cGLfloat

proc setUniformV4*[T](loc: GLint, vecs: var openarray[TV4[T]]) =
proc setUniformV4*[T](loc: GLint, vecs: var openArray[TV4[T]]) =
glUniform4fv(loc, vecs.len.GLsizei, cast[ptr GLfloat](vecs[0].addr))

proc setUniformV4*[T](loc: GLint, vec: TV4[T]) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ proc newVert*(rect: rect.TRect): seq[TVert] =
proc newVertAttrib(i: GLuint, size: GLint, stride: GLsizei, offset: GLvoid): TVertAttrib =
TVertAttrib(i: i, size: size, stride: stride, offset: offset)

proc genBuf*[T](vboTarget, objUsage: GLenum, data: var openarray[T]): GLuint =
proc genBuf*[T](vboTarget, objUsage: GLenum, data: var openArray[T]): GLuint =
result = 0.GLuint
?glGenBuffers(1, result.addr)
?glBindBuffer(vboTarget, result)
Expand Down
11 changes: 11 additions & 0 deletions tests/misc/mjsondoc.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
proc doSomething*(x, y: int): int =
## do something
x + y

const
a* = 1 ## echo 1234
b* = "test"

type
MyEnum* = enum
foo, bar
2 changes: 1 addition & 1 deletion tests/misc/t9039.nim
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ but expression 'nesting + 1' is of type: int
# line 15
func default(T: typedesc[array]): T = discard
doAssert default(array[3, int]) == [0, 0, 0]
func shapeBad*[T: not char](s: openarray[T], rank: static[int], nesting = 0, parent_shape = default(array[rank, int])): array[rank, int] =
func shapeBad*[T: not char](s: openArray[T], rank: static[int], nesting = 0, parent_shape = default(array[rank, int])): array[rank, int] =
result = parent_shape
result[nesting] = s.len
when (T is seq|array):
Expand Down
2 changes: 1 addition & 1 deletion tests/misc/theaproots.nim
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ proc acc(x: var Foo): var ref Bar =

proc test(maybeFoo: var Foo,
maybeSeq: var seq[ref Bar],
bars: var openarray[ref Bar],
bars: var openArray[ref Bar],
maybeTup: var Tup) =
var bb: ref Bar
maybeFoo.rmaybe = bb
Expand Down
1 change: 1 addition & 0 deletions tests/misc/tlocals.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
discard """
matrix: "--mm:refc; --mm:orc"
output: '''(x: "string here", a: 1)
b is 5
x is 12'''
Expand Down
17 changes: 17 additions & 0 deletions tests/misc/trunner.nim
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,23 @@ sub/mmain.idx""", context
let cmd = fmt"{nim} r --backend:{mode} --hints:off --nimcache:{nimcache} {file}"
check execCmdEx(cmd) == ("ok3\n", 0)

block: # nim jsondoc # bug #20132
let file = testsDir / "misc/mjsondoc.nim"
let output = "nimcache_tjsondoc.json"
defer: removeFile(output)
let (msg, exitCode) = execCmdEx(fmt"{nim} jsondoc -o:{output} {file}")
doAssert exitCode == 0, msg

let data = parseJson(readFile(output))["entries"]
doAssert data.len == 4
let doSomething = data[0]
doAssert doSomething["name"].getStr == "doSomething"
doAssert doSomething["type"].getStr == "skProc"
doAssert doSomething["line"].getInt == 1
doAssert doSomething["col"].getInt == 0
doAssert doSomething["code"].getStr == "proc doSomething(x, y: int): int {.raises: [], tags: [].}"


block: # further issues with `--backend`
let file = testsDir / "misc/mbackend.nim"
var cmd = fmt"{nim} doc -b:cpp --hints:off --nimcache:{nimcache} {file}"
Expand Down
2 changes: 1 addition & 1 deletion tests/misc/tsimplesort.nim
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ proc initTable*[A, B](initialSize=64): TTable[A, B] =
result.counter = 0
newSeq(result.data, initialSize)

proc toTable*[A, B](pairs: openarray[tuple[key: A,
proc toTable*[A, B](pairs: openArray[tuple[key: A,
val: B]]): TTable[A, B] =
## creates a new hash table that contains the given `pairs`.
result = initTable[A, B](nextPowerOfTwo(pairs.len+10))
Expand Down
8 changes: 8 additions & 0 deletions tests/modules/a/module_name_clashes.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# See `tmodule_name_clashes`

import ../b/module_name_clashes
type A* = object
b*: B

proc print*(a: A) =
echo repr a
3 changes: 3 additions & 0 deletions tests/modules/b/module_name_clashes.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# See `tmodule_name_clashes`

type B* = object
16 changes: 16 additions & 0 deletions tests/modules/tmodule_name_clashes.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
discard """
targets: "c"
ccodecheck: "\\i @('atmaatsmodule_name_clashesdotnim_DatInit000')"
ccodecheck: "\\i @('atmbatsmodule_name_clashesdotnim_DatInit000')"
joinable: false
"""

# Test module name clashes within same package.
# This was created to test that module symbol mangling functioned correctly
# for the C backend when there are one or more modules with the same name in
# a package, and more than one of them require module initialization procs.
# I'm not sure of the simplest method to cause the init procs to be generated.

import a/module_name_clashes

print A()
2 changes: 1 addition & 1 deletion tests/openarray/topena1.nim
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ discard """
# Tests a special bug

var
x: ref openarray[string] #ERROR_MSG invalid type
x: ref openArray[string] #ERROR_MSG invalid type
4 changes: 2 additions & 2 deletions tests/openarray/topenarrayrepr.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ discard """
output: "5 - [1]"
"""
type
TProc = proc (n: int, m: openarray[int64]) {.nimcall.}
TProc = proc (n: int, m: openArray[int64]) {.nimcall.}

proc Foo(x: int, P: TProc) =
P(x, [ 1'i64 ])

proc Bar(n: int, m: openarray[int64]) =
proc Bar(n: int, m: openArray[int64]) =
echo($n & " - " & repr(m))

Foo(5, Bar) #OUT 5 - [1]
2 changes: 1 addition & 1 deletion tests/openarray/topenlen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ discard """

proc choose(b: openArray[string]): string = return b[0]

proc p(a, b: openarray[string]): int =
proc p(a, b: openArray[string]): int =
result = a.len + b.len - 1
for j in 0 .. a.len: inc(result)
discard choose(a)
Expand Down
6 changes: 3 additions & 3 deletions tests/openarray/tptrarrayderef.nim
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ var
raa = [11,12,13]

#bug #3586
proc mutate[T](arr:openarray[T], brr: openArray[T]) =
proc mutate[T](arr:openArray[T], brr: openArray[T]) =
for i in 0..arr.len-1:
doAssert(arr[i] == brr[i])

mutate(arr, arr)

#bug #2240
proc f(a: openarray[int], b: openArray[int]) =
proc f(a: openArray[int], b: openArray[int]) =
for i in 0..a.len-1:
doAssert(a[i] == b[i])

Expand All @@ -37,7 +37,7 @@ ra[2] = 13
f(ra[], raa)

#bug #2240b
proc fillBuffer(buf: var openarray[char]) =
proc fillBuffer(buf: var openArray[char]) =
for i in 0..buf.len-1:
buf[i] = chr(i)

Expand Down
4 changes: 2 additions & 2 deletions tests/overload/toverload_various.nim
Original file line number Diff line number Diff line change
Expand Up @@ -264,8 +264,8 @@ proc init*[T](hmctx: HMAC[T], key: ptr byte, ulen: uint) =
const sizeBlock = hmctx.sizeBlock
echo sizeBlock

proc hmac*[A, B](HashType: typedesc, key: openarray[A],
data: openarray[B]) =
proc hmac*[A, B](HashType: typedesc, key: openArray[A],
data: openArray[B]) =
var ctx: HMAC[HashType]
ctx.init(nil, 0)

Expand Down
Empty file.
2 changes: 2 additions & 0 deletions tests/package/stdlib/system.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# this module is part of tstdlib_name_not_special
doAssert true
3 changes: 3 additions & 0 deletions tests/package/tstdlib_name_not_special.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Test whether a another package named 'stdlib' can be imported and used.
# This caused a crash in the past.
import stdlib/system
7 changes: 7 additions & 0 deletions tests/pragmas/tcustom_pragma.nim
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,13 @@ block:

discard Hello(a: 1.0, b: 12)

# custom pragma on iterators
block:
template prag {.pragma.}
{.push prag.}
proc hello = discard
iterator hello2: int = discard

# issue #11511
when false:
template myAttr {.pragma.}
Expand Down
4 changes: 2 additions & 2 deletions tests/showoff/tdrdobbs_examples.nim
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ const msb3999 = mostSignificantBit(3999)

echo msb3999, " ", mostSignificantBit(0), " ", square(44)

proc filter[T](a: openarray[T], predicate: proc (x: T): bool): seq[T] =
proc filter[T](a: openArray[T], predicate: proc (x: T): bool): seq[T] =
result = @[] # @[] constructs the empty seq
for x in a:
if predicate(x): result.add(x)

proc map[T, S](a: openarray[T], fn: proc (x: T): S): seq[S] =
proc map[T, S](a: openArray[T], fn: proc (x: T): S): seq[S] =
newSeq(result, a.len)
for i in 0 ..< a.len: result[i] = fn(a[i])

Expand Down
2 changes: 2 additions & 0 deletions tests/stdlib/config.nims
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
switch("styleCheck", "usages")
switch("styleCheck", "error")
4 changes: 2 additions & 2 deletions tests/stdlib/nre/misc.nim
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ block: # Misc tests
check("перевірка".replace(re"(*U)\w", "") == "")

block: # empty or non-empty match
check("abc".findall(re"|.").join(":") == ":a::b::c:")
check("abc".findall(re".|").join(":") == "a:b:c:")
check("abc".findAll(re"|.").join(":") == ":a::b::c:")
check("abc".findAll(re".|").join(":") == "a:b:c:")

check("abc".replace(re"|.", "x") == "xxxxxxx")
check("abc".replace(re".|", "x") == "xxxx")
Expand Down
4 changes: 2 additions & 2 deletions tests/stdlib/talgorithm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@ block:
doAssert binarySearch(noData, 7) == -1
let oneData = @[1]
doAssert binarySearch(oneData, 1) == 0
doAssert binarySearch(onedata, 7) == -1
doAssert binarySearch(oneData, 7) == -1
let someData = @[1, 3, 4, 7]
doAssert binarySearch(someData, 1) == 0
doAssert binarySearch(somedata, 7) == 3
doAssert binarySearch(someData, 7) == 3
doAssert binarySearch(someData, -1) == -1
doAssert binarySearch(someData, 5) == -1
doAssert binarySearch(someData, 13) == -1
Expand Down
8 changes: 4 additions & 4 deletions tests/stdlib/tasynchttpserver.nim
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ proc testCustomContentLength() {.async.} =

runTest(handler, request, test)

waitfor(test200())
waitfor(test404())
waitfor(testCustomEmptyHeaders())
waitfor(testCustomContentLength())
waitFor(test200())
waitFor(test404())
waitFor(testCustomEmptyHeaders())
waitFor(testCustomContentLength())

echo "OK"
6 changes: 3 additions & 3 deletions tests/stdlib/tbase64.nim
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ template main() =
const tests = ["", "abc", "xyz", "man", "leasure.", "sure.", "easure.",
"asure.", longText, testInputExpandsTo76, testInputExpands]

doAssert encodeMIME("foobarbaz", lineLen=4) == "Zm9v\r\nYmFy\r\nYmF6"
doAssert encodeMime("foobarbaz", lineLen=4) == "Zm9v\r\nYmFy\r\nYmF6"
doAssert decode("Zm9v\r\nYmFy\r\nYmF6") == "foobarbaz"

for t in items(tests):
doAssert decode(encode(t)) == t
doAssert decode(encodeMIME(t, lineLen=40)) == t
doAssert decode(encodeMIME(t, lineLen=76)) == t
doAssert decode(encodeMime(t, lineLen=40)) == t
doAssert decode(encodeMime(t, lineLen=76)) == t

doAssertRaises(ValueError): discard decode("SGVsbG\x008gV29ybGQ=")

Expand Down
4 changes: 2 additions & 2 deletions tests/stdlib/tbitops.nim
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,8 @@ proc main() =
doAssert v == 0b1000_0010
v.flipBit(1)
doAssert v == 0b1000_0000
doAssert v.testbit(7)
doAssert not v.testbit(6)
doAssert v.testBit(7)
doAssert not v.testBit(6)
block:
# multi bit operations
var v: uint8
Expand Down
4 changes: 4 additions & 0 deletions tests/stdlib/tdb_mysql.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import std/db_mysql

doAssert dbQuote("SELECT * FROM foo WHERE col1 = 'bar_baz'") == "'SELECT * FROM foo WHERE col1 = \\'bar_baz\\''"
doAssert dbQuote("SELECT * FROM foo WHERE col1 LIKE '%bar_baz%'") == "'SELECT * FROM foo WHERE col1 LIKE \\'%bar_baz%\\''"
2 changes: 1 addition & 1 deletion tests/stdlib/thttpclient.nim
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ proc makeIPv6HttpServer(hostname: string, port: Port,
let fd = createNativeSocket(AF_INET6)
setSockOptInt(fd, SOL_SOCKET, SO_REUSEADDR, 1)
var aiList = getAddrInfo(hostname, port, AF_INET6)
if bindAddr(fd, aiList.ai_addr, aiList.ai_addrlen.Socklen) < 0'i32:
if bindAddr(fd, aiList.ai_addr, aiList.ai_addrlen.SockLen) < 0'i32:
freeAddrInfo(aiList)
raiseOSError(osLastError())
freeAddrInfo(aiList)
Expand Down
4 changes: 2 additions & 2 deletions tests/stdlib/tjsonmacro.nim
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ proc testJson() =
colors: array[2, BirdColor]

var red = BirdColor(name: "red", rgb: [1.0, 0.0, 0.0])
var blue = Birdcolor(name: "blue", rgb: [0.0, 0.0, 1.0])
var blue = BirdColor(name: "blue", rgb: [0.0, 0.0, 1.0])
var b = Bird(age: 3, height: 1.734, name: "bardo", colors: [red, blue])
let jnode = %b
let data = jnode.to(Bird)
Expand Down Expand Up @@ -497,7 +497,7 @@ proc testJson() =
doAssert array[3, float](t.arr) == [1.0,2.0,7.0]

doAssert MyRef(t.person).name == "boney"
doAssert MyObj(t.distFruit).color == 11
doAssert MyObj(t.distfruit).color == 11
doAssert t.dog.name == "honey"
doAssert t.fruit.color == 10
doAssert seq[string](t.emails) == @["abc", "123"]
Expand Down
2 changes: 1 addition & 1 deletion tests/stdlib/tjsonutils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ template fn() =
b: int

var a = A()
fromJson(a, """{"is_a": true, "a":1, "extra_key": 1}""".parse_json, Joptions(allowExtraKeys: true))
fromJson(a, """{"is_a": true, "a":1, "extra_key": 1}""".parseJson, Joptions(allowExtraKeys: true))
doAssert $a[] == "(is_a: true, a: 1)"

block testAllowMissingKeys:
Expand Down
2 changes: 1 addition & 1 deletion tests/stdlib/tnet.nim
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ block: # "IpAddress/Sockaddr conversion"
doAssert($ipaddrstr == $ipaddr_1)

var sockaddr: Sockaddr_storage
var socklen: Socklen
var socklen: SockLen
var ipaddr_2: IpAddress
var port_2: Port

Expand Down
2 changes: 1 addition & 1 deletion tests/stdlib/tnetdial.nim
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ proc initIPv6Server(hostname: string, port: Port): AsyncFD =
let fd = createNativeSocket(AF_INET6)
setSockOptInt(fd, SOL_SOCKET, SO_REUSEADDR, 1)
var aiList = getAddrInfo(hostname, port, AF_INET6)
if bindAddr(fd, aiList.ai_addr, aiList.ai_addrlen.Socklen) < 0'i32:
if bindAddr(fd, aiList.ai_addr, aiList.ai_addrlen.SockLen) < 0'i32:
freeAddrInfo(aiList)
raiseOSError(osLastError())
freeAddrInfo(aiList)
Expand Down
2 changes: 1 addition & 1 deletion tests/stdlib/tosproc.nim
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ see also: tests/osproc/*.nim; consider merging those into a single test here

when defined(case_testfile): # compiled test file for child process
from posix import exitnow
proc c_exit2(code: c_int): void {.importc: "_exit", header: "<unistd.h>".}
proc c_exit2(code: cint): void {.importc: "_exit", header: "<unistd.h>".}
import os
var a = 0
proc fun(b = 0) =
Expand Down
4 changes: 2 additions & 2 deletions tests/stdlib/tparseipv6.nim
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,12 @@ const
"::a:b:85:e4d9:252.9.229.056",
]

proc ok(pos: openarray[string]) =
proc ok(pos: openArray[string]) =
for p in pos:
if not isIpAddress(p):
echo "failure ", p

proc notok(neg: openarray[string]) =
proc notok(neg: openArray[string]) =
for n in neg:
if isIpAddress(n):
echo "failure ", n
Expand Down
86 changes: 43 additions & 43 deletions tests/stdlib/tparsesql.nim
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ nkStmtList
nkIntegerLit 10
nkNumericLit 5.5"""

doAssert $parseSQL("SELECT foo FROM table;") == "select foo from table;"
doAssert $parseSQL("""
doAssert $parseSql("SELECT foo FROM table;") == "select foo from table;"
doAssert $parseSql("""
SELECT
CustomerName,
ContactName,
Expand All @@ -31,26 +31,26 @@ SELECT
Country
FROM table;""") == "select CustomerName, ContactName, Address, City, PostalCode, Country, CustomerName, ContactName, Address, City, PostalCode, Country from table;"

doAssert $parseSQL("SELECT foo FROM table limit 10") == "select foo from table limit 10;"
doAssert $parseSQL("SELECT foo, bar, baz FROM table limit 10") == "select foo, bar, baz from table limit 10;"
doAssert $parseSQL("SELECT foo AS bar FROM table") == "select foo as bar from table;"
doAssert $parseSQL("SELECT foo AS foo_prime, bar AS bar_prime, baz AS baz_prime FROM table") == "select foo as foo_prime, bar as bar_prime, baz as baz_prime from table;"
doAssert $parseSQL("SELECT * FROM table") == "select * from table;"
doAssert $parseSQL("SELECT count(*) FROM table") == "select count(*) from table;"
doAssert $parseSQL("SELECT count(*) as 'Total' FROM table") == "select count(*) as 'Total' from table;"
doAssert $parseSQL("SELECT count(*) as 'Total', sum(a) as 'Aggr' FROM table") == "select count(*) as 'Total', sum(a) as 'Aggr' from table;"
doAssert $parseSql("SELECT foo FROM table limit 10") == "select foo from table limit 10;"
doAssert $parseSql("SELECT foo, bar, baz FROM table limit 10") == "select foo, bar, baz from table limit 10;"
doAssert $parseSql("SELECT foo AS bar FROM table") == "select foo as bar from table;"
doAssert $parseSql("SELECT foo AS foo_prime, bar AS bar_prime, baz AS baz_prime FROM table") == "select foo as foo_prime, bar as bar_prime, baz as baz_prime from table;"
doAssert $parseSql("SELECT * FROM table") == "select * from table;"
doAssert $parseSql("SELECT count(*) FROM table") == "select count(*) from table;"
doAssert $parseSql("SELECT count(*) as 'Total' FROM table") == "select count(*) as 'Total' from table;"
doAssert $parseSql("SELECT count(*) as 'Total', sum(a) as 'Aggr' FROM table") == "select count(*) as 'Total', sum(a) as 'Aggr' from table;"

doAssert $parseSQL("""
doAssert $parseSql("""
SELECT * FROM table
WHERE a = b and c = d
""") == "select * from table where a = b and c = d;"

doAssert $parseSQL("""
doAssert $parseSql("""
SELECT * FROM table
WHERE not b
""") == "select * from table where not b;"

doAssert $parseSQL("""
doAssert $parseSql("""
SELECT
*
FROM
Expand All @@ -59,63 +59,63 @@ WHERE
a and not b
""") == "select * from table where a and not b;"

doAssert $parseSQL("""
doAssert $parseSql("""
SELECT * FROM table
ORDER BY 1
""") == "select * from table order by 1;"

doAssert $parseSQL("""
doAssert $parseSql("""
SELECT * FROM table
GROUP BY 1
ORDER BY 1
""") == "select * from table group by 1 order by 1;"

doAssert $parseSQL("""
doAssert $parseSql("""
SELECT * FROM table
ORDER BY 1
LIMIT 100
""") == "select * from table order by 1 limit 100;"

doAssert $parseSQL("""
doAssert $parseSql("""
SELECT * FROM table
WHERE a = b and c = d or n is null and not b + 1 = 3
""") == "select * from table where a = b and c = d or n is null and not b + 1 = 3;"

doAssert $parseSQL("""
doAssert $parseSql("""
SELECT * FROM table
WHERE (a = b and c = d) or (n is null and not b + 1 = 3)
""") == "select * from table where(a = b and c = d) or (n is null and not b + 1 = 3);"

doAssert $parseSQL("""
doAssert $parseSql("""
SELECT * FROM table
HAVING a = b and c = d
""") == "select * from table having a = b and c = d;"

doAssert $parseSQL("""
doAssert $parseSql("""
SELECT a, b FROM table
GROUP BY a
""") == "select a, b from table group by a;"

doAssert $parseSQL("""
doAssert $parseSql("""
SELECT a, b FROM table
GROUP BY 1, 2
""") == "select a, b from table group by 1, 2;"

doAssert $parseSQL("SELECT t.a FROM t as t") == "select t.a from t as t;"
doAssert $parseSql("SELECT t.a FROM t as t") == "select t.a from t as t;"

doAssert $parseSQL("""
doAssert $parseSql("""
SELECT a, b FROM (
SELECT * FROM t
)
""") == "select a, b from(select * from t);"

doAssert $parseSQL("""
doAssert $parseSql("""
SELECT a, b FROM (
SELECT * FROM t
) as foo
""") == "select a, b from(select * from t) as foo;"

doAssert $parseSQL("""
doAssert $parseSql("""
SELECT a, b FROM (
SELECT * FROM (
SELECT * FROM (
Expand All @@ -127,49 +127,49 @@ SELECT a, b FROM (
) as inner5
""") == "select a, b from(select * from(select * from(select * from(select * from innerTable as inner1) as inner2) as inner3) as inner4) as inner5;"

doAssert $parseSQL("""
doAssert $parseSql("""
SELECT a, b FROM
(SELECT * FROM a),
(SELECT * FROM b),
(SELECT * FROM c)
""") == "select a, b from(select * from a),(select * from b),(select * from c);"

doAssert $parseSQL("""
doAssert $parseSql("""
SELECT * FROM Products
WHERE Price BETWEEN 10 AND 20;
""") == "select * from Products where Price between 10 and 20;"

doAssert $parseSQL("""
doAssert $parseSql("""
SELECT id FROM a
JOIN b
ON a.id == b.id
""") == "select id from a join b on a.id == b.id;"

doAssert $parseSQL("""
doAssert $parseSql("""
SELECT id FROM a
JOIN (SELECT id from c) as b
ON a.id == b.id
""") == "select id from a join(select id from c) as b on a.id == b.id;"

doAssert $parseSQL("""
doAssert $parseSql("""
SELECT id FROM a
INNER JOIN b
ON a.id == b.id
""") == "select id from a inner join b on a.id == b.id;"

doAssert $parseSQL("""
doAssert $parseSql("""
SELECT id FROM a
OUTER JOIN b
ON a.id == b.id
""") == "select id from a outer join b on a.id == b.id;"

doAssert $parseSQL("""
doAssert $parseSql("""
SELECT id FROM a
CROSS JOIN b
ON a.id == b.id
""") == "select id from a cross join b on a.id == b.id;"

doAssert $parseSQL("""
doAssert $parseSql("""
CREATE TYPE happiness AS ENUM ('happy', 'very happy', 'ecstatic');
CREATE TABLE holidays (
num_weeks int,
Expand All @@ -179,16 +179,16 @@ CREATE INDEX table1_attr1 ON table1(attr1);
SELECT * FROM myTab WHERE col1 = 'happy';
""") == "create type happiness as enum ('happy' , 'very happy' , 'ecstatic' ); create table holidays(num_weeks int , happiness happiness );; create index table1_attr1 on table1(attr1 );; select * from myTab where col1 = 'happy';"

doAssert $parseSQL("""
doAssert $parseSql("""
INSERT INTO Customers (CustomerName, ContactName, Address, City, PostalCode, Country)
VALUES ('Cardinal', 'Tom B. Erichsen', 'Skagen 21', 'Stavanger', '4006', 'Norway');
""") == "insert into Customers (CustomerName , ContactName , Address , City , PostalCode , Country ) values ('Cardinal' , 'Tom B. Erichsen' , 'Skagen 21' , 'Stavanger' , '4006' , 'Norway' );"

doAssert $parseSQL("""
doAssert $parseSql("""
INSERT INTO TableName DEFAULT VALUES
""") == "insert into TableName default values;"

doAssert $parseSQL("""
doAssert $parseSql("""
UPDATE Customers
SET ContactName = 'Alfred Schmidt', City= 'Frankfurt'
WHERE CustomerID = 1;
Expand All @@ -209,24 +209,24 @@ nkStmtList
nkStringLit Frankfurt
nkNone"""

doAssert $parseSQL("DELETE FROM table_name;") == "delete from table_name;"
doAssert $parseSql("DELETE FROM table_name;") == "delete from table_name;"

doAssert treeRepr(parseSQL("DELETE FROM table_name;")
doAssert treeRepr(parseSql("DELETE FROM table_name;")
) == """

nkStmtList
nkDelete
nkIdent table_name
nkNone"""

doAssert $parseSQL("DELETE * FROM table_name;") == "delete from table_name;"
doAssert $parseSql("DELETE * FROM table_name;") == "delete from table_name;"

doAssert $parseSQL("""
doAssert $parseSql("""
--Select all:
SELECT * FROM Customers;
""") == "select * from Customers;"

doAssert $parseSQL("""
doAssert $parseSql("""
SELECT * FROM Customers WHERE (CustomerName LIKE 'L%'
OR CustomerName LIKE 'R%' /*OR CustomerName LIKE 'S%'
OR CustomerName LIKE 'T%'*/ OR CustomerName LIKE 'W%')
Expand All @@ -235,9 +235,9 @@ ORDER BY CustomerName;
""") == "select * from Customers where(CustomerName like 'L%' or CustomerName like 'R%' or CustomerName like 'W%') and Country = 'USA' order by CustomerName;"

# parse quoted keywords as identifires
doAssert $parseSQL("""
doAssert $parseSql("""
SELECT `SELECT`, `FROM` as `GROUP` FROM `WHERE`;
""") == """select "SELECT", "FROM" as "GROUP" from "WHERE";"""
doAssert $parseSQL("""
doAssert $parseSql("""
SELECT "SELECT", "FROM" as "GROUP" FROM "WHERE";
""") == """select "SELECT", "FROM" as "GROUP" from "WHERE";"""
4 changes: 4 additions & 0 deletions tests/stdlib/tpegs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ block:
privateAccess(NonTerminal)
privateAccess(Captures)

if "test" =~ peg"s <- {{\ident}}": # bug #19104
doAssert matches[0] == "test"
doAssert matches[1] == "test", $matches[1]

doAssert escapePeg("abc''def'") == r"'abc'\x27\x27'def'\x27"
doAssert match("(a b c)", peg"'(' @ ')'")
doAssert match("W_HI_Le", peg"\y 'while'")
Expand Down
202 changes: 201 additions & 1 deletion tests/stdlib/tpunycode.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,205 @@
import punycode
import punycode, std/unicode

doAssert(decode(encode("", "bücher")) == "bücher")
doAssert(decode(encode("münchen")) == "münchen")
doAssert encode("xn--", "münchen") == "xn--mnchen-3ya"

# source: https://datatracker.ietf.org/doc/html/rfc3492.html#section-7
let punycode_testcases = [
# (A) Arabic (Egyptian):
(
input:
"\u0644\u064A\u0647\u0645\u0627\u0628\u062A\u0643\u0644" &
"\u0645\u0648\u0634\u0639\u0631\u0628\u064A\u061F",
output:
"egbpdaj6bu4bxfgehfvwxn"
),

# (B) Chinese (simplified):
(
input:
"\u4ED6\u4EEC\u4E3A\u4EC0\u4E48\u4E0D\u8BF4\u4E2D\u6587",
output:
"ihqwcrb4cv8a8dqg056pqjye"
),

# (C) Chinese (traditional):
(
input:
"\u4ED6\u5011\u7232\u4EC0\u9EBD\u4E0D\u8AAA\u4E2D\u6587",
output:
"ihqwctvzc91f659drss3x8bo0yb"
),

# (D) Czech: Pro<ccaron>prost<ecaron>nemluv<iacute><ccaron>esky
(
input:
"\u0050\u0072\u006F\u010D\u0070\u0072\u006F\u0073\u0074" &
"\u011B\u006E\u0065\u006D\u006C\u0075\u0076\u00ED\u010D" &
"\u0065\u0073\u006B\u0079",
output:
"Proprostnemluvesky-uyb24dma41a"
),

# (E) Hebrew:
(
input:
"\u05DC\u05DE\u05D4\u05D4\u05DD\u05E4\u05E9\u05D5\u05D8" &
"\u05DC\u05D0\u05DE\u05D3\u05D1\u05E8\u05D9\u05DD\u05E2" &
"\u05D1\u05E8\u05D9\u05EA",
output:
"4dbcagdahymbxekheh6e0a7fei0b"
),

# (F) Hindi (Devanagari):
(
input:
"\u092F\u0939\u0932\u094B\u0917\u0939\u093F\u0928\u094D" &
"\u0926\u0940\u0915\u094D\u092F\u094B\u0902\u0928\u0939" &
"\u0940\u0902\u092C\u094B\u0932\u0938\u0915\u0924\u0947" &
"\u0939\u0948\u0902",
output:
"i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd"
),

# (G) Japanese (kanji and hiragana):
(
input:
"\u306A\u305C\u307F\u3093\u306A\u65E5\u672C\u8A9E\u3092" &
"\u8A71\u3057\u3066\u304F\u308C\u306A\u3044\u306E\u304B",
output:
"n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa"
),

# (H) Korean (Hangul syllables):
(
input:
"\uC138\uACC4\uC758\uBAA8\uB4E0\uC0AC\uB78C\uB4E4\uC774" &
"\uD55C\uAD6D\uC5B4\uB97C\uC774\uD574\uD55C\uB2E4\uBA74" &
"\uC5BC\uB9C8\uB098\uC88B\uC744\uAE4C",
output:
"989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5jpsd879ccm6fea98c"
),

# (I) Russian (Cyrillic):
(
input:
"\u043F\u043E\u0447\u0435\u043C\u0443\u0436\u0435\u043E" &
"\u043D\u0438\u043D\u0435\u0433\u043E\u0432\u043E\u0440" &
"\u044F\u0442\u043F\u043E\u0440\u0443\u0441\u0441\u043A" &
"\u0438",
output:
"b1abfaaepdrnnbgefbaDotcwatmq2g4l"
),

# (J) Spanish: Porqu<eacute>nopuedensimplementehablarenEspa<ntilde>ol
(
input:
"\u0050\u006F\u0072\u0071\u0075\u00E9\u006E\u006F\u0070" &
"\u0075\u0065\u0064\u0065\u006E\u0073\u0069\u006D\u0070" &
"\u006C\u0065\u006D\u0065\u006E\u0074\u0065\u0068\u0061" &
"\u0062\u006C\u0061\u0072\u0065\u006E\u0045\u0073\u0070" &
"\u0061\u00F1\u006F\u006C",
output:
"PorqunopuedensimplementehablarenEspaol-fmd56a"
),

# (K) Vietnamese:
# T<adotbelow>isaoh<odotbelow>kh<ocirc>ngth<ecirchookabove>ch\
# <ihookabove>n<oacute>iti<ecircacute>ngVi<ecircdotbelow>t
(
input:
"\u0054\u1EA1\u0069\u0073\u0061\u006F\u0068\u1ECD\u006B" &
"\u0068\u00F4\u006E\u0067\u0074\u0068\u1EC3\u0063\u0068" &
"\u1EC9\u006E\u00F3\u0069\u0074\u0069\u1EBF\u006E\u0067" &
"\u0056\u0069\u1EC7\u0074",
output:
"TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g"
),

# (L) 3<nen>B<gumi><kinpachi><sensei>
(
input:
"\u0033\u5E74\u0042\u7D44\u91D1\u516B\u5148\u751F",
output:
"3B-ww4c5e180e575a65lsy2b"
),

# (M) <amuro><namie>-with-SUPER-MONKEYS
(
input:
"\u5B89\u5BA4\u5948\u7F8E\u6075\u002D\u0077\u0069\u0074" &
"\u0068\u002D\u0053\u0055\u0050\u0045\u0052\u002D\u004D" &
"\u004F\u004E\u004B\u0045\u0059\u0053",
output:
"-with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n"
),

# (N) Hello-Another-Way-<sorezore><no><basho>
(
input:
"\u0048\u0065\u006C\u006C\u006F\u002D\u0041\u006E\u006F" &
"\u0074\u0068\u0065\u0072\u002D\u0057\u0061\u0079\u002D" &
"\u305D\u308C\u305E\u308C\u306E\u5834\u6240",
output:
"Hello-Another-Way--fc4qua05auwb3674vfr0b"
),

# (O) <hitotsu><yane><no><shita>2
(
input:
"\u3072\u3068\u3064\u5C4B\u6839\u306E\u4E0B\u0032",
output:
"2-u9tlzr9756bt3uc0v"
),

# (P) Maji<de>Koi<suru>5<byou><mae>
(
input:
"\u004D\u0061\u006A\u0069\u3067\u004B\u006F\u0069\u3059" &
"\u308B\u0035\u79D2\u524D",
output:
"MajiKoi5-783gue6qz075azm5e"
),

# (Q) <pafii>de<runba>
(
input:
"\u30D1\u30D5\u30A3\u30FC\u0064\u0065\u30EB\u30F3\u30D0",
output:
"de-jg4avhby1noc0d"
),

# (R) <sono><supiido><de>
(
input:
"\u305D\u306E\u30B9\u30D4\u30FC\u30C9\u3067",
output:
"d9juau41awczczp"
),

# (S) -> $1.00 <-
(
input:
"\u002D\u003E\u0020\u0024\u0031\u002E\u0030\u0030\u0020" &
"\u003C\u002D",
output:
"-> $1.00 <--"
)
]

block encodeTests:
for (uni, puny) in punycode_testcases:
# Need to convert both strings to lower case, since
# some of the extended encodings use upper case, but our
# code produces only lower case. Converting just puny to
# lower is also insufficient, since some of the input characters
# are upper case.
doAssert encode(uni).toLower() == puny.toLower()

block decodeTests:
for (uni, puny) in punycode_testcases:
doAssert decode(puny) == uni

block decodeInvalidTest:
doAssertRaises(PunyError): discard decode("xn--w&")
2 changes: 1 addition & 1 deletion tests/stdlib/trepr.nim
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ template main() =
doAssert repr(arr) == "[1, 2, 3]"

block: # bug #7878
proc reprOpenarray(variable: var openarray[int]): string = repr(variable)
proc reprOpenarray(variable: var openArray[int]): string = repr(variable)
when defined(js): discard # BUG: doesn't work
else:
doAssert reprOpenarray(arr) == "[1, 2, 3]"
Expand Down
37 changes: 32 additions & 5 deletions tests/stdlib/trst.nim
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,33 @@ suite "RST parsing":
rnLeaf 'desc2'
""")

test "no blank line is required before or after Markdown code block":
check(dedent"""
Some text
```
CodeBlock()
```
Other text""".toAst ==
dedent"""
rnInner
rnParagraph
rnLeaf 'Some'
rnLeaf ' '
rnLeaf 'text'
rnParagraph
rnCodeBlock
[nil]
[nil]
rnLiteralBlock
rnLeaf '
CodeBlock()
'
rnLeaf ' '
rnLeaf 'Other'
rnLeaf ' '
rnLeaf 'text'
""")

test "option list has priority over definition list":
check(dedent"""
defName
Expand Down Expand Up @@ -408,7 +435,7 @@ suite "RST include directive":
test "Include whole":
"other.rst".writeFile("**test1**")
let input = ".. include:: other.rst"
doAssert "<strong>test1</strong>" == rstTohtml(input, {roSandboxDisabled}, defaultConfig())
doAssert "<strong>test1</strong>" == rstToHtml(input, {roSandboxDisabled}, defaultConfig())
removeFile("other.rst")

test "Include starting from":
Expand All @@ -422,7 +449,7 @@ OtherStart
.. include:: other.rst
:start-after: OtherStart
"""
check "<em>Visible</em>" == rstTohtml(input, {roSandboxDisabled}, defaultConfig())
check "<em>Visible</em>" == rstToHtml(input, {roSandboxDisabled}, defaultConfig())
removeFile("other.rst")

test "Include everything before":
Expand All @@ -436,7 +463,7 @@ And this should **NOT** be visible in `docs.html`
.. include:: other.rst
:end-before: OtherEnd
"""
doAssert "<em>Visible</em>" == rstTohtml(input, {roSandboxDisabled}, defaultConfig())
doAssert "<em>Visible</em>" == rstToHtml(input, {roSandboxDisabled}, defaultConfig())
removeFile("other.rst")


Expand All @@ -454,7 +481,7 @@ And this should **NOT** be visible in `docs.html`
:start-after: OtherStart
:end-before: OtherEnd
"""
check "<em>Visible</em>" == rstTohtml(input, {roSandboxDisabled}, defaultConfig())
check "<em>Visible</em>" == rstToHtml(input, {roSandboxDisabled}, defaultConfig())
removeFile("other.rst")


Expand All @@ -474,7 +501,7 @@ And this should **NOT** be visible in `docs.html`
:start-after: OtherStart
:end-before: OtherEnd
"""
doAssert "<em>Visible</em>" == rstTohtml(input, {roSandboxDisabled}, defaultConfig())
doAssert "<em>Visible</em>" == rstToHtml(input, {roSandboxDisabled}, defaultConfig())
removeFile("other.rst")

suite "RST escaping":
Expand Down
8 changes: 4 additions & 4 deletions tests/stdlib/trstgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ Some chapter

"""
var error9Bad = new string
let output9Bad = input9bad.toHtml(error=error9Bad)
let output9Bad = input9Bad.toHtml(error=error9Bad)
check(error9Bad[] == "input(15, 1) Error: new section expected (section " &
"level inconsistent: underline ~~~~~ unexpectedly found, while " &
"the following intermediate section level(s) are missing on " &
Expand Down Expand Up @@ -464,7 +464,7 @@ Some chapter
rstGenera.initRstGenerator(outHtml, defaultConfig(), "input", filenames = files)
rstGenera.renderRstToOut(rst, output)
doAssert rstGenera.meta[metaTitle] == "Title0"
doAssert rstGenera.meta[metaSubTitle] == "SubTitle0"
doAssert rstGenera.meta[metaSubtitle] == "SubTitle0"
doAssert "<h1 id=\"level1\"><center>Level1</center></h1>" in output
doAssert "<h2 id=\"level2\">Level2</h2>" in output
doAssert "<h3 id=\"level3\"><center>Level3</center></h3>" in output
Expand All @@ -491,7 +491,7 @@ Some chapter
rstGenera.initRstGenerator(outHtml, defaultConfig(), "input", filenames=files)
rstGenera.renderRstToOut(rst, output)
doAssert rstGenera.meta[metaTitle] == ""
doAssert rstGenera.meta[metaSubTitle] == ""
doAssert rstGenera.meta[metaSubtitle] == ""
doAssert "<h1 id=\"title0\"><center>Title0</center></h1>" in output
doAssert "<h2 id=\"subtitle0\"><center>SubTitle0</center></h2>" in output

Expand Down Expand Up @@ -521,7 +521,7 @@ Some chapter
rstGenera.initRstGenerator(outHtml, defaultConfig(), "input", filenames=files)
rstGenera.renderRstToOut(rst, output)
doAssert rstGenera.meta[metaTitle] == "Title0"
doAssert rstGenera.meta[metaSubTitle] == ""
doAssert rstGenera.meta[metaSubtitle] == ""
doAssert output ==
"\n<h1 id=\"mysection1a\">MySection1a</h1>" & # RST
"\n<h1 id=\"mysection1b\">MySection1b</h1>" & # Markdown
Expand Down
2 changes: 1 addition & 1 deletion tests/stdlib/tsha1.nim
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ checkVector("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
proc testIsValidSha1Hash =
doAssert not isValidSha1Hash("")
doAssert not isValidSha1Hash("042D4BE2B90ED0672E717D71850ABDB0A2D19CD11")
doAssert not isValidSha1hash("042G4BE2B90ED0672E717D71850ABDB0A2D19CD1")
doAssert not isValidSha1Hash("042G4BE2B90ED0672E717D71850ABDB0A2D19CD1")
doAssert isValidSha1Hash("042D4BE2B90ED0672E717D71850ABDB0A2D19CD1")
doAssert isValidSha1Hash("042d4be2b90ed0672e717d71850abdb0a2d19cd1")
doAssert isValidSha1Hash("042d4be2b90ed0672e717D71850ABDB0A2D19CD1")
Expand Down
4 changes: 2 additions & 2 deletions tests/stdlib/tssl.nim
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ proc notifiedShutdown(port: Port) {.thread.} =
proc main() =
when defined(posix):
var
ignoreAction = SigAction(sa_handler: SIG_IGN)
oldSigPipeHandler: SigAction
ignoreAction = Sigaction(sa_handler: SIG_IGN)
oldSigPipeHandler: Sigaction
if sigemptyset(ignoreAction.sa_mask) == -1:
raiseOSError(osLastError(), "Couldn't create an empty signal set")
if sigaction(SIGPIPE, ignoreAction, oldSigPipeHandler) == -1:
Expand Down
2 changes: 1 addition & 1 deletion tests/stdlib/tstrbasics.nim
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ proc main() =

block: # setSlice
var a = "Hello, Nim!"
doassert a.dup(setSlice(7 .. 9)) == "Nim"
doAssert a.dup(setSlice(7 .. 9)) == "Nim"
doAssert a.dup(setSlice(0 .. 0)) == "H"
doAssert a.dup(setSlice(0 .. 1)) == "He"
doAssert a.dup(setSlice(0 .. 10)) == a
Expand Down
12 changes: 11 additions & 1 deletion tests/stdlib/tstreams.nim
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ block tstreams2:
block tstreams3:
try:
var fs = openFileStream("shouldneverexist.txt")
except IoError:
except IOError:
echo "threw exception"

static:
Expand Down Expand Up @@ -85,3 +85,13 @@ block:
static: # Ensure streams it doesnt break with nimscript on arc/orc #19716
let s = newStringStream("a")
doAssert s.data == "a"

template main =
var strm = newStringStream("abcde")
var buffer = "12345"
doAssert strm.readDataStr(buffer, 0..3) == 4
doAssert buffer == "abcd5"
strm.close()

static: main()
main()
60 changes: 34 additions & 26 deletions tests/stdlib/tstrscans.nim
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,23 @@ block ParsePasswd:
else:
break

const etc_passwd = """root:x:0:0:root:/root:/bin/bash
const etcPasswd = """root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
messagebus:x:103:107::/var/run/dbus:/bin/false
"""

const parsed_etc_passwd = @[
const parsedEtcPasswd = @[
"root:x:0:0:root:/root:/bin/bash",
"daemon:x:1:1:daemon:/usr/sbin:/bin/sh",
"bin:x:2:2:bin:/bin:/bin/sh",
"sys:x:3:3:sys:/dev:/bin/sh",
"nobody:x:65534:65534:nobody:/nonexistent:/bin/sh",
"messagebus:x:103:107::/var/run/dbus:/bin/false",
]
doAssert etc_passwd.parsePasswd == parsed_etc_passwd
doAssert etcPasswd.parsePasswd == parsedEtcPasswd

block LastNot:
var idx : int
Expand Down Expand Up @@ -139,27 +139,27 @@ block:
break

var key, val: string
var intval: int
var floatval: float
doAssert scanf("abc:: xyz 89 33.25", "$w$s::$s$w$s$i $f", key, val, intval, floatVal)
var intVal: int
var floatVal: float
doAssert scanf("abc:: xyz 89 33.25", "$w$s::$s$w$s$i $f", key, val, intVal, floatVal)
doAssert key == "abc"
doAssert val == "xyz"
doAssert intval == 89
doAssert intVal == 89
doAssert floatVal == 33.25

var binval: int
var octval: int
var hexval: int
doAssert scanf("0b0101 0o1234 0xabcd", "$b$s$o$s$h", binval, octval, hexval)
doAssert binval == 0b0101
doAssert octval == 0o1234
doAssert hexval == 0xabcd
var binVal: int
var octVal: int
var hexVal: int
doAssert scanf("0b0101 0o1234 0xabcd", "$b$s$o$s$h", binVal, octVal, hexVal)
doAssert binVal == 0b0101
doAssert octVal == 0o1234
doAssert hexVal == 0xabcd

let xx = scanf("$abc", "$$$i", intval)
let xx = scanf("$abc", "$$$i", intVal)
doAssert xx == false


let xx2 = scanf("$1234", "$$$i", intval)
let xx2 = scanf("$1234", "$$$i", intVal)
doAssert xx2

let yy = scanf(";.--Breakpoint00 [output]",
Expand Down Expand Up @@ -246,24 +246,32 @@ block:
result = 0
while start+result < input.len and input[start+result] in seps: inc result

type
ScanRetType = tuple
success: bool
lo: int
hi: int
ch: char
word: string

var res = 0
for line in input.splitLines:
let (success, lo, hi, c ,w) = scanTuple(line, "$i-$i $c: $w")
if success:
let ret: ScanRetType = scanTuple(line, "$i-$i $c: $w")
if ret.success:
inc res
doAssert res == 4

let (_, key, val, intval, floatVal) = scanTuple("abc:: xyz 89 33.25", "$w$s::$s$w$s$i $f")
let (_, key, val, intVal, floatVal) = scanTuple("abc:: xyz 89 33.25", "$w$s::$s$w$s$i $f")
doAssert key == "abc"
doAssert val == "xyz"
doAssert intval == 89
doAssert intVal == 89
doAssert floatVal == 33.25


let (_, binVal, octVal, hexVal) = scanTuple("0b0101 0o1234 0xabcd", "$b$s$o$s$h", binval, octval, hexval)
doAssert binval == 0b0101
doAssert octval == 0o1234
doAssert hexval == 0xabcd
let (_, binVal, octVal, hexVal) = scanTuple("0b0101 0o1234 0xabcd", "$b$s$o$s$h", binVal, octVal, hexVal)
doAssert binVal == 0b0101
doAssert octVal == 0o1234
doAssert hexVal == 0xabcd

var (xx,_) = scanTuple("$abc", "$$$i")
doAssert xx == false
Expand All @@ -272,9 +280,9 @@ block:
let (xx2, _) = block: scanTuple("$1234", "$$$i")
doAssert xx2

var (yy, intval2, key2) = scanTuple(";.--Breakpoint00 [output]",
var (yy, intVal2, key2) = scanTuple(";.--Breakpoint00 [output]",
"$[someSep]Breakpoint${twoDigits}$[someSep({';','.','-'})] [$+]$.",
int)
doAssert yy
doAssert key2 == "output"
doAssert intVal2 == 13
doAssert intVal2 == 13
2 changes: 1 addition & 1 deletion tests/stdlib/tstrset.nim
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ proc search(r: PRadixNode, s: string): PRadixNode =
proc contains*(r: PRadixNode, s: string): bool =
return search(r, s) != nil

proc testOrincl*(r: var PRadixNode, s: string): bool =
proc testOrIncl*(r: var PRadixNode, s: string): bool =
nil

proc incl*(r: var PRadixNode, s: string) = discard testOrIncl(r, s)
Expand Down
27 changes: 27 additions & 0 deletions tests/stdlib/tsystem.nim
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,30 @@ template main =

static: main()
main()

# bug #19967
block:
type
X = object
a: string
b: set[char]

var y = X(b: {'a'})

reset(y)

doAssert y.b == {}

block:
type
Color = enum
Red, Blue, Yellow
X = object
a: string
b: set[Color]

var y = X(b: {Red, Blue})

reset(y)
doAssert y.b == {}

2 changes: 1 addition & 1 deletion tests/stdlib/ttimes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ proc staticTz(hours, minutes, seconds: int = 0): Timezone {.noSideEffect.} =
result.utcOffset = offset
result.time = time

newTimezone("", zonedTimeFromTime, zonedTImeFromAdjTime)
newTimezone("", zonedTimeFromTime, zonedTimeFromAdjTime)

template parseTest(s, f, sExpected: string, ydExpected: int) =
let
Expand Down
2 changes: 1 addition & 1 deletion tests/stdlib/ttypeinfo.nim
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ doAssert($x4[].kind() == "akString")

block:
# gimme a new scope dammit
var myarr: array[0..4, array[0..4, string]] = [
var myArr: array[0..4, array[0..4, string]] = [
["test", "1", "2", "3", "4"], ["test", "1", "2", "3", "4"],
["test", "1", "2", "3", "4"], ["test", "1", "2", "3", "4"],
["test", "1", "2", "3", "4"]]
Expand Down
1 change: 1 addition & 0 deletions tests/stdlib/ttypeinfo.nims
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--styleCheck:off
4 changes: 2 additions & 2 deletions tests/stdlib/tunicode.nim
Original file line number Diff line number Diff line change
Expand Up @@ -218,5 +218,5 @@ block: # bug #17768
let s1 = "abcdef"
let s2 = "abcdéf"

doAssert s1.runeSubstr(0, -1) == "abcde"
doAssert s2.runeSubstr(0, -1) == "abcdé"
doAssert s1.runeSubStr(0, -1) == "abcde"
doAssert s2.runeSubStr(0, -1) == "abcdé"
2 changes: 1 addition & 1 deletion tests/stdlib/tvarints.nim
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ block:
chk 0.1
chk Inf
chk NegInf
chk Nan
chk NaN
chk 3.1415926535897932384626433

block:
Expand Down
2 changes: 1 addition & 1 deletion tests/system/tostring.nim
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ doAssert yy == ""
proc bar(arg: cstring) =
doAssert arg[0] == '\0'

proc baz(arg: openarray[char]) =
proc baz(arg: openArray[char]) =
doAssert arg.len == 0

proc stringCompare() =
Expand Down
4 changes: 2 additions & 2 deletions tests/system/tsystem_misc.nim
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,12 @@ let str = "0123456789"
foo(toOpenArrayByte(str, 0, str.high))


template boundedOpenArray[T](x: seq[T], first, last: int): openarray[T] =
template boundedOpenArray[T](x: seq[T], first, last: int): openArray[T] =
toOpenarray(x, max(0, first), min(x.high, last))

# bug #9281

proc foo[T](x: openarray[T]) =
proc foo[T](x: openArray[T]) =
echo x.len

let a = @[1, 2, 3]
Expand Down
4 changes: 2 additions & 2 deletions tests/template/otests.nim
Original file line number Diff line number Diff line change
Expand Up @@ -163,15 +163,15 @@ when true: #embeddingTest
"""

# Expression template
proc test_expression(nums: openarray[int] = []): string =
proc test_expression(nums: openArray[int] = []): string =
var i = 2
tmpli html"""
$(no_substitution())
$(substitution("Billy"))
<div id="age">Age: $($nums[i] & "!!")</div>
"""

proc test_statements(nums: openarray[int] = []): string =
proc test_statements(nums: openArray[int] = []): string =
tmpli html"""
$(test_expression(nums))
$if true {
Expand Down
2 changes: 1 addition & 1 deletion tests/template/sunset.nimf
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#? stdtmpl
#proc sunsetTemplate*(current, ticker, content: string,
# tabs: openarray[array[0..1, string]]): string =
# tabs: openArray[array[0..1, string]]): string =
# result = ""
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
Expand Down
16 changes: 16 additions & 0 deletions tests/template/t13515.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
discard """
action: compile
"""

template test: bool = true

# compiles:
if not test:
echo "wtf"

# does not compile:
template x =
if not test:
echo "wtf"

x
2 changes: 1 addition & 1 deletion tests/template/template_issues.nim
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ block t2585:
st
echo "a ", $fb

proc render(rdat: var RenderData; passes: var openarray[RenderPass]; proj: Mat2;
proc render(rdat: var RenderData; passes: var openArray[RenderPass]; proj: Mat2;
indexType = 1) =
for i in 0 ..< len(passes):
echo "blah ", repr(passes[i])
Expand Down
Loading