diff --git a/doc/tut1.rst b/doc/tut1.rst
index a7f1b741ad..161b4b904c 100644
--- a/doc/tut1.rst
+++ b/doc/tut1.rst
@@ -1441,31 +1441,111 @@ string that is "useless" and replace it with "useful".
Note: alternate ways of writing this are ``b[^8..^2] = "useful"`` or
as ``b[11..b.len-2] = "useful"`` or as ``b[11.. Error: type mismatch: got (tuple[street: string, number: int])
# but expected 'Person'
- # The following works because the field names and types are the same.
- var teacher: tuple[name: string, age: int] = ("Mark", 42)
- person = teacher
-
Even though you don't need to declare a type for a tuple to use it, tuples
created with different field names will be considered different objects despite
having the same field types.
@@ -1519,6 +1595,8 @@ variables! For example:
echo badname
echo badext
+Fields of tuples are always public, they don't need to be explicity
+marked to be exported, unlike for example fields in an object type.
Reference and pointer types
---------------------------
diff --git a/doc/tut2.rst b/doc/tut2.rst
index d0c6e72479..4c1ec57476 100644
--- a/doc/tut2.rst
+++ b/doc/tut2.rst
@@ -40,18 +40,16 @@ and more efficient code. In particular, preferring composition over inheritance
is often the better design.
-Objects
--------
+Inheritance
+-----------
-Like tuples, objects are a means to pack different values together in a
-structured way. However, objects provide many features that tuples do not:
-They provide inheritance and information hiding. Because objects encapsulate
-data, the ``T()`` object constructor should only be used internally and the
-programmer should provide a proc to initialize the object (this is called
-a *constructor*).
-
-Objects have access to their type at runtime. There is an
-``of`` operator that can be used to check the object's type:
+Inheritance in Nim is entirely optional. To enable inheritance with
+runtime type information the object needs to inherit from
+``RootObj``. This can be done directly, or indirectly by
+inheriting from an object that inherits from ``RootObj``. Usually
+types with inheritance are also marked as ``ref`` types even though
+this isn't strictly enforced. To check at runtime if an object is of a certain
+type, the ``of`` operator can be used.
.. code-block:: nim
:test: "nim c $1"
@@ -71,11 +69,6 @@ Objects have access to their type at runtime. There is an
student = Student(name: "Anton", age: 5, id: 2)
echo student[]
-Object fields that should be visible from outside the defining module have to
-be marked by ``*``. In contrast to tuples, different object types are
-never *equivalent*. New object types can only be defined within a type
-section.
-
Inheritance is done with the ``object of`` syntax. Multiple inheritance is
currently not supported. If an object type has no suitable ancestor, ``RootObj``
can be used as its ancestor, but this is only a convention. Objects that have
diff --git a/lib/js/dom.nim b/lib/js/dom.nim
index 9d6cd91525..3c6d65d8a1 100644
--- a/lib/js/dom.nim
+++ b/lib/js/dom.nim
@@ -192,7 +192,7 @@ type
Element* = ref ElementObj
ElementObj {.importc.} = object of NodeObj
- classList*: Classlist
+ classList*: ClassList
checked*: bool
defaultChecked*: bool
defaultValue*: cstring
@@ -1183,9 +1183,10 @@ proc contains*(c: ClassList, class: cstring): bool
proc toggle*(c: ClassList, class: cstring)
# Style "methods"
-proc getAttribute*(s: Style, attr: cstring, caseSensitive=false): cstring
-proc removeAttribute*(s: Style, attr: cstring, caseSensitive=false)
-proc setAttribute*(s: Style, attr, value: cstring, caseSensitive=false)
+proc getPropertyValue*(s: Style, property: cstring): cstring
+proc removeProperty*(s: Style, property: cstring)
+proc setProperty*(s: Style, property, value: cstring, priority = "")
+proc getPropertyPriority*(s: Style, property: cstring): cstring
# Event "methods"
proc preventDefault*(ev: Event)
@@ -1267,6 +1268,10 @@ proc inViewport*(el: Node): bool =
rect.right <= clientWidth().float
proc scrollTop*(e: Node): int {.importcpp: "#.scrollTop", nodecl.}
+proc scrollLeft*(e: Node): int {.importcpp: "#.scrollLeft", nodecl.}
+proc scrollHeight*(e: Node): int {.importcpp: "#.scrollHeight", nodecl.}
+proc scrollWidth*(e: Node): int {.importcpp: "#.scrollWidth", nodecl.}
proc offsetHeight*(e: Node): int {.importcpp: "#.offsetHeight", nodecl.}
+proc offsetWidth*(e: Node): int {.importcpp: "#.offsetWidth", nodecl.}
proc offsetTop*(e: Node): int {.importcpp: "#.offsetTop", nodecl.}
proc offsetLeft*(e: Node): int {.importcpp: "#.offsetLeft", nodecl.}
diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim
index 8c8838ed2e..b346c7a448 100644
--- a/lib/pure/algorithm.nim
+++ b/lib/pure/algorithm.nim
@@ -511,7 +511,7 @@ func isSorted*[T](a: openArray[T],
order = SortOrder.Ascending): bool =
## Checks to see whether ``a`` is already sorted in ``order``
## using ``cmp`` for the comparison. Parameters identical
- ## to ``sort``.
+ ## to ``sort``. Requires O(n) time.
##
## **See also:**
## * `isSorted proc<#isSorted,openArray[T]>`_
diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim
index 1c0681fada..56bda737a6 100644
--- a/lib/pure/asyncnet.nim
+++ b/lib/pure/asyncnet.nim
@@ -166,6 +166,18 @@ proc newAsyncSocket*(domain: Domain = AF_INET, sockType: SockType = SOCK_STREAM,
raiseOSError(osLastError())
result = newAsyncSocket(fd, domain, sockType, protocol, buffered)
+proc getLocalAddr*(socket: AsyncSocket): (string, Port) =
+ ## Get the socket's local address and port number.
+ ##
+ ## This is high-level interface for `getsockname`:idx:.
+ getLocalAddr(socket.fd, socket.domain)
+
+proc getPeerAddr*(socket: AsyncSocket): (string, Port) =
+ ## Get the socket's peer address and port number.
+ ##
+ ## This is high-level interface for `getpeername`:idx:.
+ getPeerAddr(socket.fd, socket.domain)
+
proc newAsyncSocket*(domain, sockType, protocol: cint,
buffered = true): AsyncSocket =
## Creates a new asynchronous socket.
diff --git a/lib/pure/mimetypes.nim b/lib/pure/mimetypes.nim
index 57ea825270..97ebd35c2b 100644
--- a/lib/pure/mimetypes.nim
+++ b/lib/pure/mimetypes.nim
@@ -1906,6 +1906,7 @@ func getExt*(mimedb: MimeDB, mimetype: string, default = "txt"): string =
for e, m in mimedb.mimes:
if m == mimeLowered:
result = e
+ break
func register*(mimedb: var MimeDB, ext: string, mimetype: string) =
## Adds ``mimetype`` to the ``mimedb``.
diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim
index 78f9a06eb3..9502b679a7 100644
--- a/lib/pure/osproc.nim
+++ b/lib/pure/osproc.nim
@@ -224,7 +224,7 @@ proc execProcesses*(cmds: openArray[string],
beforeRunEvent: proc(idx: int) = nil,
afterRunEvent: proc(idx: int, p: Process) = nil): int
{.rtl, extern: "nosp$1",
- tags: [ExecIOEffect, TimeEffect, ReadEnvEffect, RootEffect]} =
+ tags: [ExecIOEffect, TimeEffect, ReadEnvEffect, RootEffect].} =
## executes the commands `cmds` in parallel. Creates `n` processes
## that execute in parallel. The highest (absolute) return value of all processes
## is returned. Runs `beforeRunEvent` before running each command.
diff --git a/lib/system.nim b/lib/system.nim
index b75be3df56..268d6ccd31 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -904,37 +904,51 @@ proc chr*(u: range[0..255]): char {.magic: "Chr", noSideEffect.}
# built-in operators
when not defined(JS):
- proc ze*(x: int8): int {.magic: "Ze8ToI", noSideEffect.}
+ proc ze*(x: int8): int {.magic: "Ze8ToI", noSideEffect, deprecated.}
## zero extends a smaller integer type to ``int``. This treats `x` as
## unsigned.
- proc ze*(x: int16): int {.magic: "Ze16ToI", noSideEffect.}
+ ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
+
+ proc ze*(x: int16): int {.magic: "Ze16ToI", noSideEffect, deprecated.}
## zero extends a smaller integer type to ``int``. This treats `x` as
## unsigned.
+ ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
- proc ze64*(x: int8): int64 {.magic: "Ze8ToI64", noSideEffect.}
- ## zero extends a smaller integer type to ``int64``. This treats `x` as
- ## unsigned.
- proc ze64*(x: int16): int64 {.magic: "Ze16ToI64", noSideEffect.}
+ proc ze64*(x: int8): int64 {.magic: "Ze8ToI64", noSideEffect, deprecated.}
## zero extends a smaller integer type to ``int64``. This treats `x` as
## unsigned.
+ ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
- proc ze64*(x: int32): int64 {.magic: "Ze32ToI64", noSideEffect.}
+ proc ze64*(x: int16): int64 {.magic: "Ze16ToI64", noSideEffect, deprecated.}
## zero extends a smaller integer type to ``int64``. This treats `x` as
## unsigned.
- proc ze64*(x: int): int64 {.magic: "ZeIToI64", noSideEffect.}
+ ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
+
+ proc ze64*(x: int32): int64 {.magic: "Ze32ToI64", noSideEffect, deprecated.}
+ ## zero extends a smaller integer type to ``int64``. This treats `x` as
+ ## unsigned.
+ ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
+
+ proc ze64*(x: int): int64 {.magic: "ZeIToI64", noSideEffect, deprecated.}
## zero extends a smaller integer type to ``int64``. This treats `x` as
## unsigned. Does nothing if the size of an ``int`` is the same as ``int64``.
## (This is the case on 64 bit processors.)
+ ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
- proc toU8*(x: int): int8 {.magic: "ToU8", noSideEffect.}
+ proc toU8*(x: int): int8 {.magic: "ToU8", noSideEffect, deprecated.}
## treats `x` as unsigned and converts it to a byte by taking the last 8 bits
## from `x`.
- proc toU16*(x: int): int16 {.magic: "ToU16", noSideEffect.}
+ ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
+
+ proc toU16*(x: int): int16 {.magic: "ToU16", noSideEffect, deprecated.}
## treats `x` as unsigned and converts it to an ``int16`` by taking the last
## 16 bits from `x`.
- proc toU32*(x: int64): int32 {.magic: "ToU32", noSideEffect.}
+ ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
+
+ proc toU32*(x: int64): int32 {.magic: "ToU32", noSideEffect, deprecated.}
## treats `x` as unsigned and converts it to an ``int32`` by taking the
## last 32 bits from `x`.
+ ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
# integer calculations:
proc `+`*(x: int): int {.magic: "UnaryPlusI", noSideEffect.}
@@ -3877,7 +3891,7 @@ when false:
macro payload: typed {.gensym.} = blk
payload()
-when hasAlloc:
+when hasAlloc or defined(nimscript):
proc insert*(x: var string, item: string, i = 0.Natural) {.noSideEffect.} =
## inserts `item` into `x` at position `i`.
var xl = x.len
diff --git a/testament/categories.nim b/testament/categories.nim
index 77769743dd..c7365e8fdf 100644
--- a/testament/categories.nim
+++ b/testament/categories.nim
@@ -471,7 +471,8 @@ proc getPackageDir(package: string): string =
else:
result = commandOutput[0].string
-iterator listPackages(filter: PackageFilter): tuple[name, url, cmd: string] =
+iterator listPackages(filter: PackageFilter):
+ tuple[name, url, cmd: string, hasDeps: bool] =
const defaultCmd = "nimble test"
let packageList = parseFile(packageIndex)
for package in packageList.items:
@@ -482,12 +483,12 @@ iterator listPackages(filter: PackageFilter): tuple[name, url, cmd: string] =
case filter
of pfCoreOnly:
if "nim-lang" in normalize(url):
- yield (name, url, defaultCmd)
+ yield (name, url, defaultCmd, false)
of pfExtraOnly:
- for n, cmd, commit in important_packages.packages.items:
- if name == n: yield (name, url, cmd)
+ for n, cmd, commit, hasDeps in important_packages.packages.items:
+ if name == n: yield (name, url, cmd, hasDeps)
of pfAll:
- yield (name, url, defaultCmd)
+ yield (name, url, defaultCmd, false)
proc makeSupTest(test, options: string, cat: Category): TTest =
result.cat = cat
@@ -506,32 +507,47 @@ proc testNimblePackages(r: var TResults, cat: Category, filter: PackageFilter) =
let packageFileTest = makeSupTest("PackageFileParsed", "", cat)
var keepDir = false
+ var packagesDir = "pkgstemp"
try:
- for name, url, cmd in listPackages(filter):
+ for name, url, cmd, hasDep in listPackages(filter):
var test = makeSupTest(url, "", cat)
- let buildPath = "pkgstemp" / name
- let installProcess = startProcess("git", "", ["clone", url, buildPath])
- let installStatus = waitForExitEx(installProcess)
- installProcess.close
- if installStatus != QuitSuccess:
- r.addResult(test, targetC, "", "", reInstallFailed)
+ let buildPath = packagesDir / name
+ if not existsDir(buildPath):
+ if hasDep:
+ let nimbleProcess = startProcess("nimble", "", ["install", "-y", name],
+ options = {poUsePath, poStdErrToStdOut})
+ let nimbleStatus = waitForExitEx(nimbleProcess)
+ nimbleProcess.close
+ if nimbleStatus != QuitSuccess:
+ r.addResult(test, targetC, "", "", reInstallFailed)
+ keepDir = true
+ continue
+
+ let installProcess = startProcess("git", "", ["clone", url, buildPath],
+ options = {poUsePath, poStdErrToStdOut})
+ let installStatus = waitForExitEx(installProcess)
+ installProcess.close
+ if installStatus != QuitSuccess:
+ r.addResult(test, targetC, "", "", reInstallFailed)
+ keepDir = true
+ continue
+
+ let cmdArgs = parseCmdLine(cmd)
+ let buildProcess = startProcess(cmdArgs[0], buildPath, cmdArgs[1..^1],
+ options = {poUsePath, poStdErrToStdOut})
+ let buildStatus = waitForExitEx(buildProcess)
+ buildProcess.close
+ if buildStatus != QuitSuccess:
+ r.addResult(test, targetC, "", "", reBuildFailed)
keepDir = true
else:
- let cmdArgs = parseCmdLine(cmd)
- let buildProcess = startProcess(cmdArgs[0], buildPath, cmdArgs[1..^1])
- let buildStatus = waitForExitEx(buildProcess)
- buildProcess.close
- if buildStatus != QuitSuccess:
- r.addResult(test, targetC, "", "", reBuildFailed)
- keepDir = true
- else:
- r.addResult(test, targetC, "", "", reSuccess)
+ r.addResult(test, targetC, "", "", reSuccess)
r.addResult(packageFileTest, targetC, "", "", reSuccess)
except JsonParsingError:
echo("[Warning] - Cannot run nimble tests: Invalid package file.")
r.addResult(packageFileTest, targetC, "", "", reBuildFailed)
finally:
- if not keepDir: removeDir("pkgstemp")
+ if not keepDir: removeDir(packagesDir)
# ----------------------------------------------------------------------------
diff --git a/testament/important_packages.nim b/testament/important_packages.nim
index fbb3edaa8b..e4cbec7f8b 100644
--- a/testament/important_packages.nim
+++ b/testament/important_packages.nim
@@ -1,28 +1,44 @@
import strutils
-template pkg(name: string; cmd = "nimble test"; version = ""): untyped =
- packages.add((name, cmd, version))
+template pkg(name: string; cmd = "nimble test"; version = ""; hasDeps = false): untyped =
+ packages.add((name, cmd, version, hasDeps))
-var packages*: seq[tuple[name, cmd, version: string]] = @[]
+var packages*: seq[tuple[name, cmd, version: string; hasDeps: bool]] = @[]
-pkg "karax"
-pkg "cligen"
-pkg "glob"
-#pkg "regex"
-pkg "freeimage", "nim c freeimage.nim"
-pkg "zero_functional"
-pkg "nimpy", "nim c nimpy.nim"
-#pkg "nimongo", "nimble test_ci"
-pkg "inim"
-pkg "sdl1", "nim c src/sdl.nim"
-pkg "iterutils"
-pkg "gnuplot"
+pkg "arraymancer", "nim c src/arraymancer.nim", "", true
+pkg "ast_pattern_matching", "nim c tests/test1.nim"
pkg "c2nim"
-
-#[
- arraymancer
- nimpb
- jester
- nimx
-]#
+pkg "cligen", "nim c -o:cligenn cligen.nim"
+pkg "compactdict", "nim c tests/test1.nim"
+pkg "criterion"
+pkg "docopt"
+pkg "gara", "nim c tests/test_gara.nim"
+pkg "glob"
+pkg "gnuplot"
+pkg "hts", "nim c tests/all.nim"
+pkg "inim"
+pkg "itertools", "nim doc src/itertools.nim"
+pkg "iterutils"
+pkg "karax", "nim c tests/tester.nim"
+pkg "loopfusion"
+pkg "nake", "nim c nakefile.nim"
+pkg "neo", "nim c -d:blas=openblas tests/all.nim", "", true
+pkg "nigui", "nim c -o:niguii src/nigui.nim"
+pkg "NimData", "nim c -o:nimdataa src/nimdata.nim", "", true
+pkg "nimes", "nim c src/nimes.nim", "", true
+pkg "nimgame2", "nim c nimgame2/nimgame.nim", "", true
+pkg "nimongo", "nimble test_ci", "", true
+pkg "nimpy", "nim c -o:nimpyy nimpy.nim"
+pkg "nimsl", "nim c test.nim"
+pkg "nimx", "nim c --threads:on test/main.nim", "", true
+pkg "parsetoml"
+pkg "patty"
+pkg "plotly", "nim c examples/all.nim", "", true
+pkg "protobuf", "nim c -o:protobuff src/protobuf.nim", "", true
+pkg "regex", "nim c src/regex"
+pkg "rosencrantz", "nim c -o:rsncntz rosencrantz.nim"
+pkg "sdl1", "nim c src/sdl.nim"
+pkg "sdl2_nim", "nim c sdl2/sdl.nim"
+pkg "stint", "nim c -o:stintt stint.nim"
+pkg "zero_functional", "nim c test.nim"
diff --git a/tests/async/tasyncawait.nim b/tests/async/tasyncawait.nim
index 1e6cf3761a..063c8317cc 100644
--- a/tests/async/tasyncawait.nim
+++ b/tests/async/tasyncawait.nim
@@ -26,6 +26,10 @@ proc launchSwarm(port: Port) {.async.} =
proc readMessages(client: AsyncFD) {.async.} =
# wrapping the AsyncFd into a AsyncSocket object
var sockObj = newAsyncSocket(client)
+ var (ipaddr, port) = sockObj.getPeerAddr()
+ doAssert ipaddr == "127.0.0.1"
+ (ipaddr, port) = sockObj.getLocalAddr()
+ doAssert ipaddr == "127.0.0.1"
while true:
var line = await recvLine(sockObj)
if line == "":
diff --git a/tests/js/tbasicenum.nim b/tests/js/tbasicenum.nim
deleted file mode 100644
index a9e9ce2dac..0000000000
--- a/tests/js/tbasicenum.nim
+++ /dev/null
@@ -1,10 +0,0 @@
-discard """
- output: "ABCDC"
-"""
-
-type
- MyEnum = enum
- A,B,C,D
-# trick the optimizer with an seq:
-var x = @[A,B,C,D]
-echo x[0],x[1],x[2],x[3],MyEnum(2)
\ No newline at end of file
diff --git a/tests/js/tbasics.nim b/tests/js/tbasics.nim
new file mode 100644
index 0000000000..0c8d33e7fd
--- /dev/null
+++ b/tests/js/tbasics.nim
@@ -0,0 +1,37 @@
+discard """
+ output: '''ABCDC
+1
+14
+ok'''
+"""
+
+type
+ MyEnum = enum
+ A,B,C,D
+# trick the optimizer with an seq:
+var x = @[A,B,C,D]
+echo x[0],x[1],x[2],x[3],MyEnum(2)
+
+# bug #10651
+
+var xa: seq[int]
+var ya = @[1,2]
+xa &= ya
+echo xa[0]
+
+proc test =
+ var yup: seq[int]
+ try:
+ yup.add 14
+ echo yup.pop
+ finally:
+ discard
+
+test()
+
+when true:
+ var a: seq[int]
+
+ a.setLen(0)
+
+ echo "ok"
\ No newline at end of file