mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-31 10:53:40 +00:00
Compare commits
87 Commits
pr_holey_e
...
v2.0.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b47747d318 | ||
|
|
5667fbfbf3 | ||
|
|
d4b58b0b06 | ||
|
|
ef356cfd4b | ||
|
|
e374759f29 | ||
|
|
0de70dc7f3 | ||
|
|
2f15b67fd9 | ||
|
|
e03667e920 | ||
|
|
11c048b06f | ||
|
|
22de3ae53e | ||
|
|
3be2514683 | ||
|
|
57658b685c | ||
|
|
5f6ff1f051 | ||
|
|
7e6f4723c3 | ||
|
|
4a1151d6b4 | ||
|
|
9994b019c5 | ||
|
|
bb930aef2d | ||
|
|
be66aedb9e | ||
|
|
4bc305db1e | ||
|
|
fdb1f4451d | ||
|
|
02497c9533 | ||
|
|
0acdce502c | ||
|
|
fe1d4a6232 | ||
|
|
c4c44d10df | ||
|
|
55bb60a56b | ||
|
|
ef8b8317ff | ||
|
|
fff127bec7 | ||
|
|
7b5289a1a4 | ||
|
|
3a0d09c1c5 | ||
|
|
3ab6012c81 | ||
|
|
add124e07a | ||
|
|
8834f3e74d | ||
|
|
489dd89a45 | ||
|
|
ba9effc8a1 | ||
|
|
0d93fdf607 | ||
|
|
b8cec0c714 | ||
|
|
4793fc0fc1 | ||
|
|
e1b44666b0 | ||
|
|
194d21a6e4 | ||
|
|
1b80f7126a | ||
|
|
1dc85802e2 | ||
|
|
9e081579bb | ||
|
|
30dad5dfa1 | ||
|
|
6d32066055 | ||
|
|
86e5545c25 | ||
|
|
f4e80d51ff | ||
|
|
1db305af1c | ||
|
|
805b4e2dc2 | ||
|
|
e8e9948223 | ||
|
|
75441dcdc3 | ||
|
|
d30565f810 | ||
|
|
5c916b645b | ||
|
|
9ad184841e | ||
|
|
7536d7f94a | ||
|
|
ee0d3f9b34 | ||
|
|
d3cf815dbe | ||
|
|
b477c2adcc | ||
|
|
78d4aa3d01 | ||
|
|
855f5c8b81 | ||
|
|
7ab0f3beec | ||
|
|
ba8c9a9d1e | ||
|
|
87c1200c93 | ||
|
|
d46e71bea3 | ||
|
|
4cf2658235 | ||
|
|
5fa48e97b6 | ||
|
|
562fb0d14b | ||
|
|
320ecc69a0 | ||
|
|
106cf7a9f7 | ||
|
|
7221c6f156 | ||
|
|
4a7cdaecb4 | ||
|
|
81d58d2cc8 | ||
|
|
1080f5eba2 | ||
|
|
18e62ad136 | ||
|
|
f03aa1d0b5 | ||
|
|
ef63d47ecd | ||
|
|
0a58af8cbf | ||
|
|
8359f9683a | ||
|
|
c3425c05e9 | ||
|
|
3fa378533a | ||
|
|
4850bb5a59 | ||
|
|
037f536e7e | ||
|
|
287fbc5fb5 | ||
|
|
f553288db3 | ||
|
|
e0e386314f | ||
|
|
1de6a7a023 | ||
|
|
d1db4c29fa | ||
|
|
a488067a41 |
6
.github/workflows/ci_bench.yml
vendored
6
.github/workflows/ci_bench.yml
vendored
@@ -21,10 +21,10 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: 'Install node.js 16.x'
|
||||
uses: actions/setup-node@v3
|
||||
- name: 'Install node.js 20.x'
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '16.x'
|
||||
node-version: '20.x'
|
||||
|
||||
- name: 'Install dependencies (Linux amd64)'
|
||||
if: runner.os == 'Linux' && matrix.cpu == 'amd64'
|
||||
|
||||
2
.github/workflows/ci_docs.yml
vendored
2
.github/workflows/ci_docs.yml
vendored
@@ -47,7 +47,7 @@ jobs:
|
||||
- target: windows
|
||||
os: windows-2019
|
||||
- target: osx
|
||||
os: macos-11
|
||||
os: macos-12
|
||||
|
||||
name: ${{ matrix.target }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
8
.github/workflows/ci_packages.yml
vendored
8
.github/workflows/ci_packages.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-20.04, macos-11]
|
||||
os: [ubuntu-20.04, macos-12]
|
||||
cpu: [amd64]
|
||||
batch: ["allowed_failures", "0_3", "1_3", "2_3"] # list of `index_num`
|
||||
name: '${{ matrix.os }} (batch: ${{ matrix.batch }})'
|
||||
@@ -32,10 +32,10 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: 'Install node.js 16.x'
|
||||
uses: actions/setup-node@v3
|
||||
- name: 'Install node.js 20.x'
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '16.x'
|
||||
node-version: '20.x'
|
||||
|
||||
- name: 'Install dependencies (Linux amd64)'
|
||||
if: runner.os == 'Linux' && matrix.cpu == 'amd64'
|
||||
|
||||
6
.github/workflows/ci_publish.yml
vendored
6
.github/workflows/ci_publish.yml
vendored
@@ -21,10 +21,10 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: 'Install node.js 16.x'
|
||||
uses: actions/setup-node@v3
|
||||
- name: 'Install node.js 20.x'
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '16.x'
|
||||
node-version: '20.x'
|
||||
|
||||
- name: 'Install dependencies (Linux amd64)'
|
||||
if: runner.os == 'Linux' && matrix.cpu == 'amd64'
|
||||
|
||||
@@ -29,10 +29,10 @@ jobs:
|
||||
# vmImage: 'ubuntu-18.04'
|
||||
# CPU: i386
|
||||
OSX_amd64:
|
||||
vmImage: 'macOS-11'
|
||||
vmImage: 'macOS-12'
|
||||
CPU: amd64
|
||||
OSX_amd64_cpp:
|
||||
vmImage: 'macOS-11'
|
||||
vmImage: 'macOS-12'
|
||||
CPU: amd64
|
||||
NIM_COMPILE_TO_CPP: true
|
||||
Windows_amd64_batch0_3:
|
||||
|
||||
@@ -898,6 +898,7 @@ type
|
||||
info*: TLineInfo
|
||||
when defined(nimsuggest):
|
||||
endInfo*: TLineInfo
|
||||
hasUserSpecifiedType*: bool # used for determining whether to display inlay type hints
|
||||
owner*: PSym
|
||||
flags*: TSymFlags
|
||||
ast*: PNode # syntax tree of proc, iterator, etc.:
|
||||
|
||||
@@ -616,7 +616,7 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
|
||||
if t.kind == tyInt64: prc64[m] else: prc[m])
|
||||
putIntoDest(p, d, e, "($#)($#)" % [getTypeDesc(p.module, e.typ), res])
|
||||
else:
|
||||
let res = "($1)($2 $3 $4)" % [getTypeDesc(p.module, e.typ), rdLoc(a), rope(opr[m]), rdLoc(b)]
|
||||
let res = "($1)(($2) $3 ($4))" % [getTypeDesc(p.module, e.typ), rdLoc(a), rope(opr[m]), rdLoc(b)]
|
||||
putIntoDest(p, d, e, res)
|
||||
|
||||
proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
|
||||
@@ -1501,6 +1501,7 @@ proc genNewSeqOfCap(p: BProc; e: PNode; d: var TLoc) =
|
||||
getSeqPayloadType(p.module, seqtype),
|
||||
])
|
||||
else:
|
||||
if d.k == locNone: getTemp(p, e.typ, d, needsInit=false) # bug #22560
|
||||
putIntoDest(p, d, e, ropecg(p.module,
|
||||
"($1)#nimNewSeqOfCap($2, $3)", [
|
||||
getTypeDesc(p.module, seqtype),
|
||||
@@ -1550,6 +1551,7 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
|
||||
|
||||
var tmp: TLoc
|
||||
var r: Rope
|
||||
let needsZeroMem = p.config.selectedGC notin {gcArc, gcAtomicArc, gcOrc} or nfAllFieldsSet notin e.flags
|
||||
if useTemp:
|
||||
getTemp(p, t, tmp)
|
||||
r = rdLoc(tmp)
|
||||
@@ -1558,10 +1560,13 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
|
||||
t = t.lastSon.skipTypes(abstractInstOwned)
|
||||
r = "(*$1)" % [r]
|
||||
gcUsage(p.config, e)
|
||||
else:
|
||||
elif needsZeroMem:
|
||||
constructLoc(p, tmp)
|
||||
else:
|
||||
genObjectInit(p, cpsStmts, t, tmp, constructObj)
|
||||
else:
|
||||
resetLoc(p, d)
|
||||
if needsZeroMem: resetLoc(p, d)
|
||||
else: genObjectInit(p, cpsStmts, d.t, d, if isRef: constructRefObj else: constructObj)
|
||||
r = rdLoc(d)
|
||||
discard getTypeDesc(p.module, t)
|
||||
let ty = getUniqueType(t)
|
||||
@@ -1876,9 +1881,9 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||
if optBoundsCheck in p.options:
|
||||
genBoundsCheck(p, m, b, c)
|
||||
if op == mHigh:
|
||||
putIntoDest(p, d, e, ropecg(p.module, "($2)-($1)", [rdLoc(b), rdLoc(c)]))
|
||||
putIntoDest(p, d, e, ropecg(p.module, "(($2)-($1))", [rdLoc(b), rdLoc(c)]))
|
||||
else:
|
||||
putIntoDest(p, d, e, ropecg(p.module, "($2)-($1)+1", [rdLoc(b), rdLoc(c)]))
|
||||
putIntoDest(p, d, e, ropecg(p.module, "(($2)-($1)+1)", [rdLoc(b), rdLoc(c)]))
|
||||
else:
|
||||
if not reifiedOpenArray(a):
|
||||
if op == mHigh: unaryExpr(p, e, d, "($1Len_0-1)")
|
||||
|
||||
@@ -83,7 +83,7 @@ proc specializeResetT(p: BProc, accessor: Rope, typ: PType) =
|
||||
lineCg(p, cpsStmts, "$1.ClP_0 = NIM_NIL;$n", [accessor])
|
||||
else:
|
||||
lineCg(p, cpsStmts, "$1 = NIM_NIL;$n", [accessor])
|
||||
of tyChar, tyBool, tyEnum, tyInt..tyUInt64:
|
||||
of tyChar, tyBool, tyEnum, tyRange, tyInt..tyUInt64:
|
||||
lineCg(p, cpsStmts, "$1 = 0;$n", [accessor])
|
||||
of tyCstring, tyPointer, tyPtr, tyVar, tyLent:
|
||||
lineCg(p, cpsStmts, "$1 = NIM_NIL;$n", [accessor])
|
||||
@@ -97,7 +97,7 @@ proc specializeResetT(p: BProc, accessor: Rope, typ: PType) =
|
||||
else:
|
||||
doAssert false, "unexpected set type kind"
|
||||
of {tyNone, tyEmpty, tyNil, tyUntyped, tyTyped, tyGenericInvocation,
|
||||
tyGenericParam, tyOrdinal, tyRange, tyOpenArray, tyForward, tyVarargs,
|
||||
tyGenericParam, tyOrdinal, tyOpenArray, tyForward, tyVarargs,
|
||||
tyUncheckedArray, tyProxy, tyBuiltInTypeClass, tyUserTypeClass,
|
||||
tyUserTypeClassInst, tyCompositeTypeClass, tyAnd, tyOr, tyNot,
|
||||
tyAnything, tyStatic, tyFromExpr, tyConcept, tyVoid, tyIterable}:
|
||||
|
||||
@@ -54,13 +54,31 @@ proc mangleField(m: BModule; name: PIdent): string =
|
||||
if isKeyword(name):
|
||||
result.add "_0"
|
||||
|
||||
proc mangleProc(m: BModule; s: PSym; makeUnique: bool): string =
|
||||
result = "_Z" # Common prefix in Itanium ABI
|
||||
result.add encodeSym(m, s, makeUnique)
|
||||
if s.typ.len > 1: #we dont care about the return param
|
||||
for i in 1..<s.typ.len:
|
||||
if s.typ[i].isNil: continue
|
||||
result.add encodeType(m, s.typ[i])
|
||||
|
||||
if result in m.g.mangledPrcs:
|
||||
result = mangleProc(m, s, true)
|
||||
else:
|
||||
m.g.mangledPrcs.incl(result)
|
||||
|
||||
proc fillBackendName(m: BModule; s: PSym) =
|
||||
if s.loc.r == "":
|
||||
var result = s.name.s.mangle.rope
|
||||
result.add "__"
|
||||
result.add m.g.graph.ifaces[s.itemId.module].uniqueName
|
||||
result.add "_u"
|
||||
result.addInt s.itemId.item # s.disamb #
|
||||
var result: Rope
|
||||
if s.kind in routineKinds and optCDebug in m.g.config.globalOptions and
|
||||
m.g.config.symbolFiles == disabledSf:
|
||||
result = mangleProc(m, s, false).rope
|
||||
else:
|
||||
result = s.name.s.mangle.rope
|
||||
result.add "__"
|
||||
result.add m.g.graph.ifaces[s.itemId.module].uniqueName
|
||||
result.add "_u"
|
||||
result.addInt s.itemId.item # s.disamb #
|
||||
if m.hcrOn:
|
||||
result.add '_'
|
||||
result.add(idOrSig(s, m.module.name.s.mangle, m.sigConflicts, m.config))
|
||||
|
||||
@@ -13,6 +13,8 @@ import
|
||||
ast, types, hashes, strutils, msgs, wordrecg,
|
||||
platform, trees, options, cgendata
|
||||
|
||||
import std/[hashes, strutils, formatfloat]
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
@@ -121,10 +123,10 @@ proc mapSetType(conf: ConfigRef; typ: PType): TCTypeKind =
|
||||
proc ccgIntroducedPtr*(conf: ConfigRef; s: PSym, retType: PType): bool =
|
||||
var pt = skipTypes(s.typ, typedescInst)
|
||||
assert skResult != s.kind
|
||||
|
||||
|
||||
#note precedence: params override types
|
||||
if optByRef in s.options: return true
|
||||
elif sfByCopy in s.flags: return false
|
||||
elif sfByCopy in s.flags: return false
|
||||
elif tfByRef in pt.flags: return true
|
||||
elif tfByCopy in pt.flags: return false
|
||||
case pt.kind
|
||||
@@ -148,3 +150,64 @@ proc ccgIntroducedPtr*(conf: ConfigRef; s: PSym, retType: PType): bool =
|
||||
result = not (pt.kind in {tyVar, tyArray, tyOpenArray, tyVarargs, tyRef, tyPtr, tyPointer} or
|
||||
pt.kind == tySet and mapSetType(conf, pt) == ctArray)
|
||||
|
||||
proc encodeName*(name: string): string =
|
||||
result = mangle(name)
|
||||
result = $result.len & result
|
||||
|
||||
proc makeUnique(m: BModule; s: PSym, name: string = ""): string =
|
||||
result = if name == "": s.name.s else: name
|
||||
result.add "__"
|
||||
result.add m.g.graph.ifaces[s.itemId.module].uniqueName
|
||||
result.add "_u"
|
||||
result.add $s.itemId.item
|
||||
|
||||
proc encodeSym*(m: BModule; s: PSym; makeUnique: bool = false): string =
|
||||
#Module::Type
|
||||
var name = s.name.s
|
||||
if makeUnique:
|
||||
name = makeUnique(m, s, name)
|
||||
"N" & encodeName(s.owner.name.s) & encodeName(name) & "E"
|
||||
|
||||
proc elementType*(n: PType): PType {.inline.} = n.sons[^1]
|
||||
|
||||
proc encodeType*(m: BModule; t: PType): string =
|
||||
result = ""
|
||||
var kindName = ($t.kind)[2..^1]
|
||||
kindName[0] = toLower($kindName[0])[0]
|
||||
case t.kind
|
||||
of tyObject, tyEnum, tyDistinct, tyUserTypeClass, tyGenericParam:
|
||||
result = encodeSym(m, t.sym)
|
||||
of tyGenericInst, tyUserTypeClassInst, tyGenericBody:
|
||||
result = encodeName(t[0].sym.name.s)
|
||||
result.add "I"
|
||||
for i in 1..<t.len - 1:
|
||||
result.add encodeType(m, t[i])
|
||||
result.add "E"
|
||||
of tySequence, tyOpenArray, tyArray, tyVarargs, tyTuple, tyProc, tySet, tyTypeDesc,
|
||||
tyPtr, tyRef, tyVar, tyLent, tySink, tyStatic, tyUncheckedArray, tyOr, tyAnd, tyBuiltInTypeClass:
|
||||
result =
|
||||
case t.kind:
|
||||
of tySequence: encodeName("seq")
|
||||
else: encodeName(kindName)
|
||||
result.add "I"
|
||||
for i in 0..<t.len:
|
||||
let s = t[i]
|
||||
if s.isNil: continue
|
||||
result.add encodeType(m, s)
|
||||
result.add "E"
|
||||
of tyRange:
|
||||
var val = "range_"
|
||||
if t.n[0].typ.kind in {tyFloat..tyFloat128}:
|
||||
val.addFloat t.n[0].floatVal
|
||||
val.add "_"
|
||||
val.addFloat t.n[1].floatVal
|
||||
else:
|
||||
val.add $t.n[0].intVal & "_" & $t.n[1].intVal
|
||||
result = encodeName(val)
|
||||
of tyString..tyUInt64, tyPointer, tyBool, tyChar, tyVoid, tyAnything, tyNil, tyEmpty:
|
||||
result = encodeName(kindName)
|
||||
of tyAlias, tyInferred, tyOwned:
|
||||
result = encodeType(m, t.elementType)
|
||||
else:
|
||||
assert false, "encodeType " & $t.kind
|
||||
|
||||
|
||||
@@ -311,10 +311,10 @@ proc genLineDir(p: BProc, t: PNode) =
|
||||
(p.prc == nil or sfPure notin p.prc.flags) and t.info.fileIndex != InvalidFileIdx:
|
||||
if freshLine:
|
||||
if lastFileIndex == t.info.fileIndex:
|
||||
linefmt(p, cpsStmts, "nimln_($1);\n",
|
||||
linefmt(p, cpsStmts, "nimln_($1);",
|
||||
[line])
|
||||
else:
|
||||
linefmt(p, cpsStmts, "nimlf_($1, $2);\n",
|
||||
linefmt(p, cpsStmts, "nimlf_($1, $2);",
|
||||
[line, quotedFilename(p.config, t.info)])
|
||||
|
||||
proc accessThreadLocalVar(p: BProc, s: PSym)
|
||||
@@ -986,11 +986,19 @@ proc closureSetup(p: BProc, prc: PSym) =
|
||||
linefmt(p, cpsStmts, "$1 = ($2) ClE_0;$n",
|
||||
[rdLoc(env.loc), getTypeDesc(p.module, env.typ)])
|
||||
|
||||
const harmless = {nkConstSection, nkTypeSection, nkEmpty, nkCommentStmt, nkTemplateDef,
|
||||
nkMacroDef, nkMixinStmt, nkBindStmt, nkFormalParams} +
|
||||
declarativeDefs
|
||||
|
||||
proc containsResult(n: PNode): bool =
|
||||
result = false
|
||||
case n.kind
|
||||
of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit, nkFormalParams:
|
||||
of succ(nkEmpty)..pred(nkSym), succ(nkSym)..nkNilLit, harmless:
|
||||
discard
|
||||
of nkReturnStmt:
|
||||
for i in 0..<n.len:
|
||||
if containsResult(n[i]): return true
|
||||
result = n.len > 0 and n[0].kind == nkEmpty
|
||||
of nkSym:
|
||||
if n.sym.kind == skResult:
|
||||
result = true
|
||||
@@ -998,10 +1006,6 @@ proc containsResult(n: PNode): bool =
|
||||
for i in 0..<n.len:
|
||||
if containsResult(n[i]): return true
|
||||
|
||||
const harmless = {nkConstSection, nkTypeSection, nkEmpty, nkCommentStmt, nkTemplateDef,
|
||||
nkMacroDef, nkMixinStmt, nkBindStmt, nkFormalParams} +
|
||||
declarativeDefs
|
||||
|
||||
proc easyResultAsgn(n: PNode): PNode =
|
||||
case n.kind
|
||||
of nkStmtList, nkStmtListExpr:
|
||||
@@ -1175,7 +1179,13 @@ proc genProcAux*(m: BModule, prc: PSym) =
|
||||
# declare the result symbol:
|
||||
assignLocalVar(p, resNode)
|
||||
assert(res.loc.r != "")
|
||||
initLocalVar(p, res, immediateAsgn=false)
|
||||
if p.config.selectedGC in {gcArc, gcAtomicArc, gcOrc} and
|
||||
allPathsAsgnResult(procBody) == InitSkippable:
|
||||
# In an ideal world the codegen could rely on injectdestructors doing its job properly
|
||||
# and then the analysis step would not be required.
|
||||
discard "result init optimized out"
|
||||
else:
|
||||
initLocalVar(p, res, immediateAsgn=false)
|
||||
returnStmt = ropecg(p.module, "\treturn $1;$n", [rdLoc(res.loc)])
|
||||
elif sfConstructor in prc.flags:
|
||||
fillLoc(resNode.sym.loc, locParam, resNode, "this", OnHeap)
|
||||
|
||||
@@ -135,6 +135,7 @@ type
|
||||
# unconditionally...
|
||||
# nimtvDeps is VERY hard to cache because it's
|
||||
# not a list of IDs nor can it be made to be one.
|
||||
mangledPrcs*: HashSet[string]
|
||||
|
||||
TCGen = object of PPassContext # represents a C source file
|
||||
s*: TCFileSections # sections of the C file
|
||||
|
||||
@@ -158,3 +158,4 @@ proc initDefines*(symbols: StringTableRef) =
|
||||
defineSymbol("nimAllowNonVarDestructor")
|
||||
defineSymbol("nimHasQuirky")
|
||||
defineSymbol("nimHasEnsureMove")
|
||||
defineSymbol("nimHasNoLineTooLong")
|
||||
|
||||
@@ -1723,7 +1723,7 @@ proc genOutFile(d: PDoc, groupedToc = false): string =
|
||||
"moduledesc", d.modDescFinal, "date", getDateStr(), "time", getClockStr(),
|
||||
"content", content, "author", d.meta[metaAuthor],
|
||||
"version", esc(d.target, d.meta[metaVersion]), "analytics", d.analytics,
|
||||
"deprecationMsg", d.modDeprecationMsg]
|
||||
"deprecationMsg", d.modDeprecationMsg, "nimVersion", $NimMajor & "." & $NimMinor & "." & $NimPatch]
|
||||
else:
|
||||
code = content
|
||||
result = code
|
||||
@@ -1907,7 +1907,7 @@ proc commandBuildIndex*(conf: ConfigRef, dir: string, outFile = RelativeFile"")
|
||||
"title", "Index",
|
||||
"subtitle", "", "tableofcontents", "", "moduledesc", "",
|
||||
"date", getDateStr(), "time", getClockStr(),
|
||||
"content", content, "author", "", "version", "", "analytics", ""]
|
||||
"content", content, "author", "", "version", "", "analytics", "", "nimVersion", $NimMajor & "." & $NimMinor & "." & $NimPatch]
|
||||
# no analytics because context is not available
|
||||
|
||||
try:
|
||||
|
||||
@@ -19,7 +19,7 @@ import std/[os, osproc, streams, sequtils, times, strtabs, json, jsonutils, suga
|
||||
import std / strutils except addf
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/syncio
|
||||
import std/[syncio, assertions]
|
||||
|
||||
import ../dist/checksums/src/checksums/sha1
|
||||
|
||||
@@ -992,7 +992,7 @@ type BuildCache = object
|
||||
depfiles: seq[(string, string)]
|
||||
nimexe: string
|
||||
|
||||
proc writeJsonBuildInstructions*(conf: ConfigRef) =
|
||||
proc writeJsonBuildInstructions*(conf: ConfigRef; deps: StringTableRef) =
|
||||
var linkFiles = collect(for it in conf.externalToLink:
|
||||
var it = it
|
||||
if conf.noAbsolutePaths: it = it.extractFilename
|
||||
@@ -1013,10 +1013,14 @@ proc writeJsonBuildInstructions*(conf: ConfigRef) =
|
||||
currentDir: getCurrentDir())
|
||||
if optRun in conf.globalOptions or isDefined(conf, "nimBetterRun"):
|
||||
bcache.cmdline = conf.commandLine
|
||||
bcache.depfiles = collect(for it in conf.m.fileInfos:
|
||||
for it in conf.m.fileInfos:
|
||||
let path = it.fullPath.string
|
||||
if isAbsolute(path): # TODO: else?
|
||||
(path, $secureHashFile(path)))
|
||||
if path in deps:
|
||||
bcache.depfiles.add (path, deps[path])
|
||||
else: # backup for configs etc.
|
||||
bcache.depfiles.add (path, $secureHashFile(path))
|
||||
|
||||
bcache.nimexe = hashNimExe()
|
||||
conf.jsonBuildFile = conf.jsonBuildInstructionsFile
|
||||
conf.jsonBuildFile.string.writeFile(bcache.toJson.pretty)
|
||||
|
||||
@@ -10,9 +10,6 @@
|
||||
# This include implements the high level optimization pass.
|
||||
# included from sem.nim
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
proc hlo(c: PContext, n: PNode): PNode
|
||||
|
||||
proc evalPattern(c: PContext, n, orig: PNode): PNode =
|
||||
|
||||
@@ -344,9 +344,11 @@ proc evalImport*(c: PContext, n: PNode): PNode =
|
||||
imp[lastPos] = x[1]
|
||||
impAs[1] = imp
|
||||
impAs[2] = x[2]
|
||||
impAs.info = x[2].info
|
||||
impMod(c, impAs, result)
|
||||
else:
|
||||
imp[lastPos] = x
|
||||
imp.info = x.info
|
||||
impMod(c, imp, result)
|
||||
else:
|
||||
impMod(c, it, result)
|
||||
|
||||
@@ -185,7 +185,9 @@ proc isCursor(n: PNode): bool =
|
||||
template isUnpackedTuple(n: PNode): bool =
|
||||
## we move out all elements of unpacked tuples,
|
||||
## hence unpacked tuples themselves don't need to be destroyed
|
||||
(n.kind == nkSym and n.sym.kind == skTemp and n.sym.typ.kind == tyTuple)
|
||||
## except it's already a cursor
|
||||
(n.kind == nkSym and n.sym.kind == skTemp and
|
||||
n.sym.typ.kind == tyTuple and sfCursor notin n.sym.flags)
|
||||
|
||||
proc checkForErrorPragma(c: Con; t: PType; ri: PNode; opname: string; inferredFromCopy = false) =
|
||||
var m = "'" & opname & "' is not available for type <" & typeToString(t) & ">"
|
||||
@@ -850,7 +852,9 @@ proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode; tmpFlags = {sfSing
|
||||
result[i][1] = p(n[i][1], c, s, m)
|
||||
else:
|
||||
result[i] = p(n[i], c, s, m)
|
||||
if mode == normal and isRefConstr:
|
||||
if mode == normal and (isRefConstr or (hasDestructor(c, t) and
|
||||
getAttachedOp(c.graph, t, attachedDestructor) != nil and
|
||||
sfOverridden in getAttachedOp(c.graph, t, attachedDestructor).flags)):
|
||||
result = ensureDestruction(result, n, c, s)
|
||||
of nkCallKinds:
|
||||
if n[0].kind == nkSym and n[0].sym.magic == mEnsureMove:
|
||||
|
||||
@@ -162,8 +162,7 @@ proc fillBodyObj(c: var TLiftCtx; n, body, x, y: PNode; enforceDefaultOp: bool)
|
||||
if c.filterDiscriminator != nil: return
|
||||
let f = n.sym
|
||||
let b = if c.kind == attachedTrace: y else: y.dotField(f)
|
||||
if (sfCursor in f.flags and f.typ.skipTypes(abstractInst).kind in {tyRef, tyProc} and
|
||||
c.g.config.selectedGC in {gcArc, gcAtomicArc, gcOrc, gcHooks}) or
|
||||
if (sfCursor in f.flags and c.g.config.selectedGC in {gcArc, gcAtomicArc, gcOrc, gcHooks}) or
|
||||
enforceDefaultOp:
|
||||
defaultOp(c, f.typ, body, x.dotField(f), b)
|
||||
else:
|
||||
|
||||
@@ -237,6 +237,9 @@ proc addField*(obj: PType; s: PSym; cache: IdentCache; idgen: IdGenerator): PSym
|
||||
field.itemId = ItemId(module: s.itemId.module, item: -s.itemId.item)
|
||||
let t = skipIntLit(s.typ, idgen)
|
||||
field.typ = t
|
||||
if s.kind in {skLet, skVar, skField, skForVar}:
|
||||
#field.bitsize = s.bitsize
|
||||
field.alignment = s.alignment
|
||||
assert t.kind != tyTyped
|
||||
propagateToOwner(obj, t)
|
||||
field.position = obj.n.len
|
||||
|
||||
@@ -151,7 +151,7 @@ proc commandCompileToC(graph: ModuleGraph) =
|
||||
extccomp.callCCompiler(conf)
|
||||
# for now we do not support writing out a .json file with the build instructions when HCR is on
|
||||
if not conf.hcrOn:
|
||||
extccomp.writeJsonBuildInstructions(conf)
|
||||
extccomp.writeJsonBuildInstructions(conf, graph.cachedFiles)
|
||||
if optGenScript in graph.config.globalOptions:
|
||||
writeDepsFile(graph)
|
||||
if optGenCDeps in graph.config.globalOptions:
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
## represents a complete Nim project. Single modules can either be kept in RAM
|
||||
## or stored in a rod-file.
|
||||
|
||||
import intsets, tables, hashes
|
||||
import std/[intsets, tables, hashes, strtabs]
|
||||
import ../dist/checksums/src/checksums/md5
|
||||
import ast, astalgo, options, lineinfos,idents, btrees, ropes, msgs, pathutils, packages
|
||||
import ic / [packed_ast, ic]
|
||||
@@ -57,6 +57,7 @@ type
|
||||
SymInfoPair* = object
|
||||
sym*: PSym
|
||||
info*: TLineInfo
|
||||
isDecl*: bool
|
||||
|
||||
PipelinePass* = enum
|
||||
NonePass
|
||||
@@ -128,6 +129,8 @@ type
|
||||
idgen*: IdGenerator
|
||||
operators*: Operators
|
||||
|
||||
cachedFiles*: StringTableRef
|
||||
|
||||
TPassContext* = object of RootObj # the pass's context
|
||||
idgen*: IdGenerator
|
||||
PPassContext* = ref TPassContext
|
||||
@@ -479,6 +482,7 @@ proc initModuleGraphFields(result: ModuleGraph) =
|
||||
result.symBodyHashes = initTable[int, SigHash]()
|
||||
result.operators = initOperators(result)
|
||||
result.emittedTypeInfo = initTable[string, FileIndex]()
|
||||
result.cachedFiles = newStringTable()
|
||||
|
||||
proc newModuleGraph*(cache: IdentCache; config: ConfigRef): ModuleGraph =
|
||||
result = ModuleGraph()
|
||||
|
||||
@@ -36,11 +36,14 @@ proc getModuleName*(conf: ConfigRef; n: PNode): string =
|
||||
localError(n.info, "only '/' supported with $package notation")
|
||||
result = ""
|
||||
else:
|
||||
let modname = getModuleName(conf, n[2])
|
||||
# hacky way to implement 'x / y /../ z':
|
||||
result = getModuleName(conf, n1)
|
||||
result.add renderTree(n0, {renderNoComments}).replace(" ")
|
||||
result.add modname
|
||||
if n0.kind == nkIdent and n0.ident.s[0] == '/':
|
||||
let modname = getModuleName(conf, n[2])
|
||||
# hacky way to implement 'x / y /../ z':
|
||||
result = getModuleName(conf, n1)
|
||||
result.add renderTree(n0, {renderNoComments}).replace(" ")
|
||||
result.add modname
|
||||
else:
|
||||
result = ""
|
||||
of nkPrefix:
|
||||
when false:
|
||||
if n[0].kind == nkIdent and n[0].ident.s == "$":
|
||||
|
||||
@@ -14,6 +14,9 @@ import
|
||||
idents, lexer, syntaxes, modulegraphs,
|
||||
lineinfos, pathutils
|
||||
|
||||
import ../dist/checksums/src/checksums/sha1
|
||||
import std/strtabs
|
||||
|
||||
proc resetSystemArtifacts*(g: ModuleGraph) =
|
||||
magicsys.resetSysTypes(g)
|
||||
|
||||
@@ -42,6 +45,8 @@ proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex): PNode =
|
||||
result = syntaxes.parseFile(fileIdx, graph.cache, graph.config)
|
||||
graph.addDep(s, fileIdx)
|
||||
graph.addIncludeDep(s.position.FileIndex, fileIdx)
|
||||
let path = toFullPath(graph.config, fileIdx)
|
||||
graph.cachedFiles[path] = $secureHashFile(path)
|
||||
|
||||
proc wantMainModule*(conf: ConfigRef) =
|
||||
if conf.projectFull.isEmpty:
|
||||
|
||||
@@ -429,7 +429,8 @@ To create a stacktrace, rerun compilation with './koch temp $1 <file>', see $2 f
|
||||
proc handleError(conf: ConfigRef; msg: TMsgKind, eh: TErrorHandling, s: string, ignoreMsg: bool) =
|
||||
if msg in fatalMsgs:
|
||||
if conf.cmd == cmdIdeTools: log(s)
|
||||
quit(conf, msg)
|
||||
if conf.cmd != cmdIdeTools or msg != errFatal:
|
||||
quit(conf, msg)
|
||||
if msg >= errMin and msg <= errMax or
|
||||
(msg in warnMin..hintMax and msg in conf.warningAsErrors and not ignoreMsg):
|
||||
inc(conf.errorCounter)
|
||||
@@ -437,7 +438,11 @@ proc handleError(conf: ConfigRef; msg: TMsgKind, eh: TErrorHandling, s: string,
|
||||
if conf.errorCounter >= conf.errorMax:
|
||||
# only really quit when we're not in the new 'nim check --def' mode:
|
||||
if conf.ideCmd == ideNone:
|
||||
quit(conf, msg)
|
||||
when defined(nimsuggest):
|
||||
#we need to inform the user that something went wrong when initializing NimSuggest
|
||||
raiseRecoverableError(s)
|
||||
else:
|
||||
quit(conf, msg)
|
||||
elif eh == doAbort and conf.cmd != cmdIdeTools:
|
||||
quit(conf, msg)
|
||||
elif eh == doRaise:
|
||||
|
||||
@@ -195,7 +195,7 @@ type
|
||||
IdeCmd* = enum
|
||||
ideNone, ideSug, ideCon, ideDef, ideUse, ideDus, ideChk, ideChkFile, ideMod,
|
||||
ideHighlight, ideOutline, ideKnown, ideMsg, ideProject, ideGlobalSymbols,
|
||||
ideRecompile, ideChanged, ideType, ideDeclaration, ideExpand
|
||||
ideRecompile, ideChanged, ideType, ideDeclaration, ideExpand, ideInlayHints
|
||||
|
||||
Feature* = enum ## experimental features; DO NOT RENAME THESE!
|
||||
dotOperators,
|
||||
@@ -280,9 +280,24 @@ type
|
||||
version*: int
|
||||
endLine*: uint16
|
||||
endCol*: int
|
||||
inlayHintInfo*: SuggestInlayHint
|
||||
|
||||
Suggestions* = seq[Suggest]
|
||||
|
||||
SuggestInlayHintKind* = enum
|
||||
sihkType = "Type",
|
||||
sihkParameter = "Parameter"
|
||||
|
||||
SuggestInlayHint* = ref object
|
||||
kind*: SuggestInlayHintKind
|
||||
line*: int # Starts at 1
|
||||
column*: int # Starts at 0
|
||||
label*: string
|
||||
paddingLeft*: bool
|
||||
paddingRight*: bool
|
||||
allowInsert*: bool
|
||||
tooltip*: string
|
||||
|
||||
ProfileInfo* = object
|
||||
time*: float
|
||||
count*: int
|
||||
@@ -417,6 +432,8 @@ type
|
||||
expandNodeResult*: string
|
||||
expandPosition*: TLineInfo
|
||||
|
||||
clientProcessId*: int
|
||||
|
||||
|
||||
proc parseNimVersion*(a: string): NimVer =
|
||||
# could be moved somewhere reusable
|
||||
@@ -1057,6 +1074,7 @@ proc `$`*(c: IdeCmd): string =
|
||||
of ideRecompile: "recompile"
|
||||
of ideChanged: "changed"
|
||||
of ideType: "type"
|
||||
of ideInlayHints: "inlayHints"
|
||||
|
||||
proc floatInt64Align*(conf: ConfigRef): int16 =
|
||||
## Returns either 4 or 8 depending on reasons.
|
||||
|
||||
@@ -1430,6 +1430,7 @@ proc parseTypeDesc(p: var Parser, fullExpr = false): PNode =
|
||||
result = newNodeP(nkObjectTy, p)
|
||||
getTok(p)
|
||||
of tkConcept:
|
||||
result = p.emptyNode
|
||||
parMessage(p, "the 'concept' keyword is only valid in 'type' sections")
|
||||
of tkVar: result = parseTypeDescKAux(p, nkVarTy, pmTypeDesc)
|
||||
of tkOut: result = parseTypeDescKAux(p, nkOutTy, pmTypeDesc)
|
||||
|
||||
@@ -5,10 +5,12 @@ import sem, cgen, modulegraphs, ast, llstream, parser, msgs,
|
||||
|
||||
import pipelineutils
|
||||
|
||||
import ../dist/checksums/src/checksums/sha1
|
||||
|
||||
when not defined(leanCompiler):
|
||||
import jsgen, docgen2
|
||||
|
||||
import std/[syncio, objectdollar, assertions, tables, strutils]
|
||||
import std/[syncio, objectdollar, assertions, tables, strutils, strtabs]
|
||||
import renderer
|
||||
import ic/replayer
|
||||
|
||||
@@ -225,7 +227,10 @@ proc compilePipelineModule*(graph: ModuleGraph; fileIdx: FileIndex; flags: TSymF
|
||||
if result == nil:
|
||||
var cachedModules: seq[FileIndex]
|
||||
result = moduleFromRodFile(graph, fileIdx, cachedModules)
|
||||
let filename = AbsoluteFile toFullPath(graph.config, fileIdx)
|
||||
let path = toFullPath(graph.config, fileIdx)
|
||||
let filename = AbsoluteFile path
|
||||
if fileExists(filename): # it could be a stdinfile
|
||||
graph.cachedFiles[path] = $secureHashFile(path)
|
||||
if result == nil:
|
||||
result = newModule(graph, fileIdx)
|
||||
result.flags.incl flags
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
{.used.}
|
||||
|
||||
import
|
||||
lexer, options, idents, strutils, ast, msgs, lineinfos
|
||||
lexer, options, idents, strutils, ast, msgs, lineinfos, wordrecg
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/[syncio, assertions, formatfloat]
|
||||
@@ -848,7 +848,7 @@ proc gcase(g: var TSrcGen, n: PNode) =
|
||||
gsub(g, n[^1], c)
|
||||
|
||||
proc genSymSuffix(result: var string, s: PSym) {.inline.} =
|
||||
if sfGenSym in s.flags:
|
||||
if sfGenSym in s.flags and s.name.id != ord(wUnderscore):
|
||||
result.add '_'
|
||||
result.addInt s.id
|
||||
|
||||
@@ -971,7 +971,9 @@ proc gident(g: var TSrcGen, n: PNode) =
|
||||
s.addInt localId
|
||||
if sfCursor in n.sym.flags:
|
||||
s.add "_cursor"
|
||||
elif n.kind == nkSym and (renderIds in g.flags or sfGenSym in n.sym.flags or n.sym.kind == skTemp):
|
||||
elif n.kind == nkSym and (renderIds in g.flags or
|
||||
(sfGenSym in n.sym.flags and n.sym.name.id != ord(wUnderscore)) or
|
||||
n.sym.kind == skTemp):
|
||||
s.add '_'
|
||||
s.addInt n.sym.id
|
||||
when defined(debugMagics):
|
||||
|
||||
@@ -26,7 +26,10 @@ when not defined(leanCompiler):
|
||||
import spawn
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/formatfloat
|
||||
import std/[
|
||||
formatfloat,
|
||||
assertions,
|
||||
]
|
||||
|
||||
# implementation
|
||||
|
||||
@@ -206,12 +209,58 @@ proc commonType*(c: PContext; x, y: PType): PType =
|
||||
result.addSonSkipIntLit(r, c.idgen)
|
||||
|
||||
proc endsInNoReturn(n: PNode): bool =
|
||||
# check if expr ends in raise exception or call of noreturn proc
|
||||
## check if expr ends the block like raising or call of noreturn procs do
|
||||
result = false # assume it does return
|
||||
|
||||
template checkBranch(branch) =
|
||||
if not endsInNoReturn(branch):
|
||||
# proved a branch returns
|
||||
return false
|
||||
|
||||
var it = n
|
||||
# skip these beforehand, no special handling needed
|
||||
while it.kind in {nkStmtList, nkStmtListExpr} and it.len > 0:
|
||||
it = it.lastSon
|
||||
result = it.kind in nkLastBlockStmts or
|
||||
it.kind in nkCallKinds and it[0].kind == nkSym and sfNoReturn in it[0].sym.flags
|
||||
|
||||
case it.kind
|
||||
of nkIfStmt:
|
||||
var hasElse = false
|
||||
for branch in it:
|
||||
checkBranch:
|
||||
if branch.len == 2:
|
||||
branch[1]
|
||||
elif branch.len == 1:
|
||||
hasElse = true
|
||||
branch[0]
|
||||
else:
|
||||
raiseAssert "Malformed `if` statement during endsInNoReturn"
|
||||
# none of the branches returned
|
||||
result = hasElse # Only truly a no-return when it's exhaustive
|
||||
of nkCaseStmt:
|
||||
for i in 1 ..< it.len:
|
||||
let branch = it[i]
|
||||
checkBranch:
|
||||
case branch.kind
|
||||
of nkOfBranch:
|
||||
branch[^1]
|
||||
of nkElifBranch:
|
||||
branch[1]
|
||||
of nkElse:
|
||||
branch[0]
|
||||
else:
|
||||
raiseAssert "Malformed `case` statement in endsInNoReturn"
|
||||
# none of the branches returned
|
||||
result = true
|
||||
of nkTryStmt:
|
||||
checkBranch(it[0])
|
||||
for i in 1 ..< it.len:
|
||||
let branch = it[i]
|
||||
checkBranch(branch[^1])
|
||||
# none of the branches returned
|
||||
result = true
|
||||
else:
|
||||
result = it.kind in nkLastBlockStmts or
|
||||
it.kind in nkCallKinds and it[0].kind == nkSym and sfNoReturn in it[0].sym.flags
|
||||
|
||||
proc commonType*(c: PContext; x: PType, y: PNode): PType =
|
||||
# ignore exception raising branches in case/if expressions
|
||||
@@ -462,7 +511,13 @@ proc semAfterMacroCall(c: PContext, call, macroResult: PNode,
|
||||
# we now know the supplied arguments
|
||||
var paramTypes = newIdTable()
|
||||
for param, value in genericParamsInMacroCall(s, call):
|
||||
idTablePut(paramTypes, param.typ, value.typ)
|
||||
var givenType = value.typ
|
||||
# the sym nodes used for the supplied generic arguments for
|
||||
# templates and macros leave type nil so regular sem can handle it
|
||||
# in this case, get the type directly from the sym
|
||||
if givenType == nil and value.kind == nkSym and value.sym.typ != nil:
|
||||
givenType = value.sym.typ
|
||||
idTablePut(paramTypes, param.typ, givenType)
|
||||
|
||||
retType = generateTypeInstance(c, paramTypes,
|
||||
macroResult.info, retType)
|
||||
|
||||
@@ -236,44 +236,89 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors):
|
||||
candidates.add("\n")
|
||||
let nArg = if err.firstMismatch.arg < n.len: n[err.firstMismatch.arg] else: nil
|
||||
let nameParam = if err.firstMismatch.formal != nil: err.firstMismatch.formal.name.s else: ""
|
||||
if n.len > 1 and verboseTypeMismatch in c.config.legacyFeatures:
|
||||
candidates.add(" first type mismatch at position: " & $err.firstMismatch.arg)
|
||||
# candidates.add "\n reason: " & $err.firstMismatch.kind # for debugging
|
||||
case err.firstMismatch.kind
|
||||
of kUnknownNamedParam:
|
||||
if nArg == nil:
|
||||
candidates.add("\n unknown named parameter")
|
||||
else:
|
||||
candidates.add("\n unknown named parameter: " & $nArg[0])
|
||||
of kAlreadyGiven: candidates.add("\n named param already provided: " & $nArg[0])
|
||||
of kPositionalAlreadyGiven: candidates.add("\n positional param was already given as named param")
|
||||
of kExtraArg: candidates.add("\n extra argument given")
|
||||
of kMissingParam: candidates.add("\n missing parameter: " & nameParam)
|
||||
of kTypeMismatch, kVarNeeded:
|
||||
doAssert nArg != nil
|
||||
let wanted = err.firstMismatch.formal.typ
|
||||
doAssert err.firstMismatch.formal != nil
|
||||
candidates.add("\n required type for " & nameParam & ": ")
|
||||
candidates.addTypeDeclVerboseMaybe(c.config, wanted)
|
||||
candidates.add "\n but expression '"
|
||||
if err.firstMismatch.kind == kVarNeeded:
|
||||
if n.len > 1:
|
||||
if verboseTypeMismatch notin c.config.legacyFeatures:
|
||||
case err.firstMismatch.kind
|
||||
of kUnknownNamedParam:
|
||||
if nArg == nil:
|
||||
candidates.add(" unknown named parameter")
|
||||
else:
|
||||
candidates.add(" unknown named parameter: " & $nArg[0])
|
||||
candidates.add "\n"
|
||||
of kAlreadyGiven:
|
||||
candidates.add(" named param already provided: " & $nArg[0])
|
||||
candidates.add "\n"
|
||||
of kPositionalAlreadyGiven:
|
||||
candidates.add(" positional param was already given as named param")
|
||||
candidates.add "\n"
|
||||
of kExtraArg:
|
||||
candidates.add(" extra argument given")
|
||||
candidates.add "\n"
|
||||
of kMissingParam:
|
||||
candidates.add(" missing parameter: " & nameParam)
|
||||
candidates.add "\n"
|
||||
of kVarNeeded:
|
||||
doAssert nArg != nil
|
||||
doAssert err.firstMismatch.formal != nil
|
||||
candidates.add " expression '"
|
||||
candidates.add renderNotLValue(nArg)
|
||||
candidates.add "' is immutable, not 'var'"
|
||||
else:
|
||||
candidates.add renderTree(nArg)
|
||||
candidates.add "' is of type: "
|
||||
let got = nArg.typ
|
||||
candidates.addTypeDeclVerboseMaybe(c.config, got)
|
||||
candidates.add "\n"
|
||||
of kTypeMismatch:
|
||||
doAssert nArg != nil
|
||||
let wanted = err.firstMismatch.formal.typ
|
||||
doAssert err.firstMismatch.formal != nil
|
||||
doAssert wanted != nil
|
||||
if got != nil:
|
||||
if got.kind == tyProc and wanted.kind == tyProc:
|
||||
# These are proc mismatches so,
|
||||
# add the extra explict detail of the mismatch
|
||||
candidates.addPragmaAndCallConvMismatch(wanted, got, c.config)
|
||||
let got = nArg.typ
|
||||
if got != nil and got.kind == tyProc and wanted.kind == tyProc:
|
||||
# These are proc mismatches so,
|
||||
# add the extra explict detail of the mismatch
|
||||
candidates.add " expression '"
|
||||
candidates.add renderTree(nArg)
|
||||
candidates.add "' is of type: "
|
||||
candidates.addTypeDeclVerboseMaybe(c.config, got)
|
||||
candidates.addPragmaAndCallConvMismatch(wanted, got, c.config)
|
||||
effectProblem(wanted, got, candidates, c)
|
||||
candidates.add "\n"
|
||||
of kUnknown: discard "do not break 'nim check'"
|
||||
else:
|
||||
candidates.add(" first type mismatch at position: " & $err.firstMismatch.arg)
|
||||
# candidates.add "\n reason: " & $err.firstMismatch.kind # for debugging
|
||||
case err.firstMismatch.kind
|
||||
of kUnknownNamedParam:
|
||||
if nArg == nil:
|
||||
candidates.add("\n unknown named parameter")
|
||||
else:
|
||||
candidates.add("\n unknown named parameter: " & $nArg[0])
|
||||
of kAlreadyGiven: candidates.add("\n named param already provided: " & $nArg[0])
|
||||
of kPositionalAlreadyGiven: candidates.add("\n positional param was already given as named param")
|
||||
of kExtraArg: candidates.add("\n extra argument given")
|
||||
of kMissingParam: candidates.add("\n missing parameter: " & nameParam)
|
||||
of kTypeMismatch, kVarNeeded:
|
||||
doAssert nArg != nil
|
||||
let wanted = err.firstMismatch.formal.typ
|
||||
doAssert err.firstMismatch.formal != nil
|
||||
candidates.add("\n required type for " & nameParam & ": ")
|
||||
candidates.addTypeDeclVerboseMaybe(c.config, wanted)
|
||||
candidates.add "\n but expression '"
|
||||
if err.firstMismatch.kind == kVarNeeded:
|
||||
candidates.add renderNotLValue(nArg)
|
||||
candidates.add "' is immutable, not 'var'"
|
||||
else:
|
||||
candidates.add renderTree(nArg)
|
||||
candidates.add "' is of type: "
|
||||
let got = nArg.typ
|
||||
candidates.addTypeDeclVerboseMaybe(c.config, got)
|
||||
doAssert wanted != nil
|
||||
if got != nil:
|
||||
if got.kind == tyProc and wanted.kind == tyProc:
|
||||
# These are proc mismatches so,
|
||||
# add the extra explict detail of the mismatch
|
||||
candidates.addPragmaAndCallConvMismatch(wanted, got, c.config)
|
||||
effectProblem(wanted, got, candidates, c)
|
||||
|
||||
of kUnknown: discard "do not break 'nim check'"
|
||||
candidates.add "\n"
|
||||
of kUnknown: discard "do not break 'nim check'"
|
||||
candidates.add "\n"
|
||||
if err.firstMismatch.arg == 1 and nArg.kind == nkTupleConstr and
|
||||
n.kind == nkCommand:
|
||||
maybeWrongSpace = true
|
||||
@@ -595,7 +640,12 @@ proc semResolvedCall(c: PContext, x: TCandidate,
|
||||
else:
|
||||
x.call.add c.graph.emptyNode
|
||||
of skType:
|
||||
x.call.add newSymNode(s, n.info)
|
||||
var tn = newSymNode(s, n.info)
|
||||
# this node will be used in template substitution,
|
||||
# pretend this is an untyped node and let regular sem handle the type
|
||||
# to prevent problems where a generic parameter is treated as a value
|
||||
tn.typ = nil
|
||||
x.call.add tn
|
||||
else:
|
||||
internalAssert c.config, false
|
||||
|
||||
@@ -665,14 +715,18 @@ proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode =
|
||||
onUse(info, s)
|
||||
result = newSymNode(newInst, info)
|
||||
|
||||
proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
|
||||
assert n.kind == nkBracketExpr
|
||||
proc setGenericParams(c: PContext, n: PNode) =
|
||||
## sems generic params in subscript expression
|
||||
for i in 1..<n.len:
|
||||
let e = semExprWithType(c, n[i])
|
||||
if e.typ == nil:
|
||||
n[i].typ = errorType(c)
|
||||
else:
|
||||
n[i].typ = e.typ.skipTypes({tyTypeDesc})
|
||||
|
||||
proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
|
||||
assert n.kind == nkBracketExpr
|
||||
setGenericParams(c, n)
|
||||
var s = s
|
||||
var a = n[0]
|
||||
if a.kind == nkSym:
|
||||
|
||||
@@ -996,10 +996,6 @@ proc bracketedMacro(n: PNode): PSym =
|
||||
if result.kind notin {skMacro, skTemplate}:
|
||||
result = nil
|
||||
|
||||
proc setGenericParams(c: PContext, n: PNode) =
|
||||
for i in 1..<n.len:
|
||||
n[i].typ = semTypeNode(c, n[i], nil)
|
||||
|
||||
proc afterCallActions(c: PContext; n, orig: PNode, flags: TExprFlags; expectedType: PType = nil): PNode =
|
||||
if efNoSemCheck notin flags and n.typ != nil and n.typ.kind == tyError:
|
||||
return errorNode(c, n)
|
||||
@@ -1106,7 +1102,6 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType
|
||||
msg.addDeclaredLocMaybe(c.config, typ)
|
||||
localError(c.config, n.info, msg)
|
||||
return errorNode(c, n)
|
||||
result = nil
|
||||
else:
|
||||
result = m.call
|
||||
instGenericConvertersSons(c, result, m)
|
||||
@@ -1845,7 +1840,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
|
||||
result.add(n[1])
|
||||
if mode == noOverloadedSubscript:
|
||||
bracketNotFoundError(c, result)
|
||||
return n
|
||||
return errorNode(c, n)
|
||||
else:
|
||||
result = semExprNoType(c, result)
|
||||
return result
|
||||
@@ -2244,7 +2239,7 @@ proc semQuoteAst(c: PContext, n: PNode): PNode =
|
||||
for i in 1..<ids.len:
|
||||
let exp = semExprWithType(c, quotes[i+1], {})
|
||||
let typ = exp.typ
|
||||
if tfTriggersCompileTime notin typ.flags and exp.kind == nkSym and exp.sym.kind notin routineKinds + {skType}:
|
||||
if tfTriggersCompileTime notin typ.flags and typ.kind != tyStatic and exp.kind == nkSym and exp.sym.kind notin routineKinds + {skType}:
|
||||
dummyTemplate[paramsPos].add newTreeI(nkIdentDefs, n.info, ids[i], newNodeIT(nkType, n.info, typ), c.graph.emptyNode)
|
||||
else:
|
||||
dummyTemplate[paramsPos].add newTreeI(nkIdentDefs, n.info, ids[i], getSysSym(c.graph, n.info, "typed").newSymNode, c.graph.emptyNode)
|
||||
|
||||
@@ -167,6 +167,17 @@ proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags,
|
||||
elif s.isMixedIn:
|
||||
result = newDot(result, symChoice(c, n, s, scForceOpen))
|
||||
else:
|
||||
if s.kind == skType and candidates.len > 1:
|
||||
var ambig = false
|
||||
let s2 = searchInScopes(c, ident, ambig)
|
||||
if ambig:
|
||||
# this is a type conversion like a.T where T is ambiguous with
|
||||
# other types or routines
|
||||
# in regular code, this never considers a type conversion and
|
||||
# skips to routine overloading
|
||||
# so symchoices are used which behave similarly with type symbols
|
||||
result = newDot(result, symChoice(c, n, s, scForceOpen))
|
||||
return
|
||||
let syms = semGenericStmtSymbol(c, n, s, ctx, flags, fromDotExpr=true)
|
||||
result = newDot(result, syms)
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ proc semArrGet(c: PContext; n: PNode; flags: TExprFlags): PNode =
|
||||
x[0] = newIdentNode(getIdent(c.cache, "[]"), n.info)
|
||||
bracketNotFoundError(c, x)
|
||||
#localError(c.config, n.info, "could not resolve: " & $n)
|
||||
result = n
|
||||
result = errorNode(c, n)
|
||||
|
||||
proc semArrPut(c: PContext; n: PNode; flags: TExprFlags): PNode =
|
||||
# rewrite `[]=`(a, i, x) back to ``a[i] = x``.
|
||||
@@ -668,7 +668,8 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
|
||||
result.typ = expectedType # type inference for empty sequence # bug #21377
|
||||
of mEnsureMove:
|
||||
result = n
|
||||
if isAssignable(c, n[1]) notin {arLValue, arLocalLValue}:
|
||||
localError(c.config, n.info, "'" & $n[1] & "'" & " is not a mutable location; it cannot be moved")
|
||||
if n[1].kind in {nkStmtListExpr, nkBlockExpr,
|
||||
nkIfExpr, nkCaseStmt, nkTryStmt}:
|
||||
localError(c.config, n.info, "Nested expressions cannot be moved: '" & $n[1] & "'")
|
||||
else:
|
||||
result = n
|
||||
|
||||
@@ -656,9 +656,11 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||
addToVarSection(c, result, b)
|
||||
continue
|
||||
|
||||
var hasUserSpecifiedType = false
|
||||
var typ: PType = nil
|
||||
if a[^2].kind != nkEmpty:
|
||||
typ = semTypeNode(c, a[^2], nil)
|
||||
hasUserSpecifiedType = true
|
||||
|
||||
var typFlags: TTypeAllowedFlags
|
||||
|
||||
@@ -730,6 +732,8 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||
addToVarSection(c, result, n, a)
|
||||
continue
|
||||
var v = semIdentDef(c, a[j], symkind, false)
|
||||
when defined(nimsuggest):
|
||||
v.hasUserSpecifiedType = hasUserSpecifiedType
|
||||
styleCheckDef(c, v)
|
||||
onDef(a[j].info, v)
|
||||
if sfGenSym notin v.flags:
|
||||
@@ -803,9 +807,11 @@ proc semConst(c: PContext, n: PNode): PNode =
|
||||
addToVarSection(c, result, b)
|
||||
continue
|
||||
|
||||
var hasUserSpecifiedType = false
|
||||
var typ: PType = nil
|
||||
if a[^2].kind != nkEmpty:
|
||||
typ = semTypeNode(c, a[^2], nil)
|
||||
hasUserSpecifiedType = true
|
||||
|
||||
var typFlags: TTypeAllowedFlags
|
||||
|
||||
@@ -846,6 +852,8 @@ proc semConst(c: PContext, n: PNode): PNode =
|
||||
else:
|
||||
for j in 0..<a.len-2:
|
||||
var v = semIdentDef(c, a[j], skConst)
|
||||
when defined(nimsuggest):
|
||||
v.hasUserSpecifiedType = hasUserSpecifiedType
|
||||
if sfGenSym notin v.flags: addInterfaceDecl(c, v)
|
||||
elif v.owner == nil: v.owner = getCurrOwner(c)
|
||||
styleCheckDef(c, v)
|
||||
@@ -2613,9 +2621,7 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags, expectedType: PType =
|
||||
var m = n[i]
|
||||
while m.kind in {nkStmtListExpr, nkStmtList} and m.len > 0: # from templates
|
||||
m = m.lastSon
|
||||
if m.kind in nkLastBlockStmts or
|
||||
m.kind in nkCallKinds and m[0].kind == nkSym and
|
||||
sfNoReturn in m[0].sym.flags:
|
||||
if endsInNoReturn(m):
|
||||
for j in i + 1..<n.len:
|
||||
case n[j].kind
|
||||
of nkPragma, nkCommentStmt, nkNilLit, nkEmpty, nkState: discard
|
||||
|
||||
@@ -566,6 +566,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
|
||||
# so we use the generic code for nkDotExpr too
|
||||
let s = qualifiedLookUp(c.c, n, {})
|
||||
if s != nil:
|
||||
# mirror the nkIdent case
|
||||
# do not symchoice a quoted template parameter (bug #2390):
|
||||
if s.owner == c.owner and s.kind == skParam and
|
||||
n.kind == nkAccQuoted and n.len == 1:
|
||||
@@ -577,7 +578,9 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
|
||||
elif contains(c.toMixin, s.name.id):
|
||||
return symChoice(c.c, n, s, scForceOpen, c.noGenSym > 0)
|
||||
else:
|
||||
return symChoice(c.c, n, s, scOpen, c.noGenSym > 0)
|
||||
if s.kind in {skType, skVar, skLet, skConst}:
|
||||
discard qualifiedLookUp(c.c, n, {checkAmbiguity, checkModule})
|
||||
return semTemplSymbol(c.c, n, s, c.noGenSym > 0)
|
||||
if n.kind == nkDotExpr:
|
||||
result = n
|
||||
result[0] = semTemplBody(c, n[0])
|
||||
@@ -673,6 +676,9 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
|
||||
# a template's parameters are not gensym'ed even if that was originally the
|
||||
# case as we determine whether it's a template parameter in the template
|
||||
# body by the absence of the sfGenSym flag:
|
||||
let retType = s.typ[0]
|
||||
if retType != nil and retType.kind != tyUntyped:
|
||||
allUntyped = false
|
||||
for i in 1..<s.typ.n.len:
|
||||
let param = s.typ.n[i].sym
|
||||
if param.name.id != ord(wUnderscore):
|
||||
|
||||
@@ -141,6 +141,7 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
|
||||
result.n.add symNode
|
||||
styleCheckDef(c, e)
|
||||
onDef(e.info, e)
|
||||
suggestSym(c.graph, e.info, e, c.graph.usageSym)
|
||||
if sfGenSym notin e.flags:
|
||||
if not isPure:
|
||||
addInterfaceOverloadableSymAt(c, c.currentScope, e)
|
||||
@@ -2113,6 +2114,9 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||
else:
|
||||
let symKind = if n.kind == nkIteratorTy: skIterator else: skProc
|
||||
result = semProcTypeWithScope(c, n, prev, symKind)
|
||||
if result == nil:
|
||||
localError(c.config, n.info, "type expected, but got: " & renderTree(n))
|
||||
result = newOrPrevType(tyError, prev, c)
|
||||
if n.kind == nkIteratorTy and result.kind == tyProc:
|
||||
result.flags.incl(tfIterator)
|
||||
of nkEnumTy: result = semEnum(c, n, prev)
|
||||
|
||||
@@ -46,7 +46,8 @@ proc searchInstTypes*(g: ModuleGraph; key: PType): PType =
|
||||
# XXX: This happens for prematurely cached
|
||||
# types such as Channel[empty]. Why?
|
||||
# See the notes for PActor in handleGenericInvocation
|
||||
return
|
||||
# if this is return the same type gets cached more than it needs to
|
||||
continue
|
||||
if not sameFlags(inst, key):
|
||||
continue
|
||||
|
||||
@@ -204,7 +205,7 @@ proc hasValuelessStatics(n: PNode): bool =
|
||||
a
|
||||
proc doThing(_: MyThing)
|
||||
]#
|
||||
if n.safeLen == 0:
|
||||
if n.safeLen == 0 and n.kind != nkEmpty: # Some empty nodes can get in here
|
||||
n.typ == nil or n.typ.kind == tyStatic
|
||||
else:
|
||||
for x in n:
|
||||
|
||||
@@ -1207,7 +1207,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
of tyArray:
|
||||
var fRange = f[0]
|
||||
var aRange = a[0]
|
||||
if fRange.kind == tyGenericParam:
|
||||
if fRange.kind in {tyGenericParam, tyAnything}:
|
||||
var prev = PType(idTableGet(c.bindings, fRange))
|
||||
if prev == nil:
|
||||
put(c, fRange, a[0])
|
||||
@@ -1536,6 +1536,8 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
if x.kind == tyGenericInvocation:
|
||||
if f[0] == x[0]:
|
||||
for i in 1..<f.len:
|
||||
# Handle when checking against a generic that isn't fully instantiated
|
||||
if i >= x.len: return
|
||||
let tr = typeRel(c, f[i], x[i], flags)
|
||||
if tr <= isSubtype: return
|
||||
result = isGeneric
|
||||
|
||||
@@ -81,7 +81,16 @@ proc cmpSuggestions(a, b: Suggest): int =
|
||||
# independent of hashing order:
|
||||
result = cmp(a.name[], b.name[])
|
||||
|
||||
proc getTokenLenFromSource(conf: ConfigRef; ident: string; info: TLineInfo): int =
|
||||
proc scanForTrailingAsterisk(line: string, start: int): int =
|
||||
result = 0
|
||||
while start+result < line.len and line[start+result] in {' ', '\t'}:
|
||||
inc result
|
||||
if start+result < line.len and line[start+result] == '*':
|
||||
inc result
|
||||
else:
|
||||
result = 0
|
||||
|
||||
proc getTokenLenFromSource(conf: ConfigRef; ident: string; info: TLineInfo; skipTrailingAsterisk: bool = false): int =
|
||||
let
|
||||
line = sourceLine(conf, info)
|
||||
column = toColumn(info)
|
||||
@@ -103,8 +112,10 @@ proc getTokenLenFromSource(conf: ConfigRef; ident: string; info: TLineInfo): int
|
||||
result = 0
|
||||
elif ident[0] in linter.Letters and ident[^1] != '=':
|
||||
result = identLen(line, column)
|
||||
if cmpIgnoreStyle(line[column..column + result - 1], ident) != 0:
|
||||
if cmpIgnoreStyle(line[column..column + result - 1], ident[0..min(result-1,len(ident)-1)]) != 0:
|
||||
result = 0
|
||||
if skipTrailingAsterisk and result > 0:
|
||||
result += scanForTrailingAsterisk(line, column + result)
|
||||
else:
|
||||
var sourceIdent: string
|
||||
result = parseWhile(line, sourceIdent,
|
||||
@@ -154,7 +165,10 @@ proc symToSuggest*(g: ModuleGraph; s: PSym, isLocal: bool, section: IdeCmd, info
|
||||
result.qualifiedPath.add(s.name.s)
|
||||
|
||||
if s.typ != nil:
|
||||
result.forth = typeToString(s.typ)
|
||||
if section == ideInlayHints:
|
||||
result.forth = typeToString(s.typ, preferInlayHint)
|
||||
else:
|
||||
result.forth = typeToString(s.typ, preferInferredEffects)
|
||||
else:
|
||||
result.forth = ""
|
||||
when defined(nimsuggest) and not defined(noDocgen) and not defined(leanCompiler):
|
||||
@@ -173,58 +187,90 @@ proc symToSuggest*(g: ModuleGraph; s: PSym, isLocal: bool, section: IdeCmd, info
|
||||
result.filePath = toFullPath(g.config, infox)
|
||||
result.line = toLinenumber(infox)
|
||||
result.column = toColumn(infox)
|
||||
result.tokenLen = if section != ideHighlight:
|
||||
result.tokenLen = if section notin {ideHighlight, ideInlayHints}:
|
||||
s.name.s.len
|
||||
else:
|
||||
getTokenLenFromSource(g.config, s.name.s, infox)
|
||||
getTokenLenFromSource(g.config, s.name.s, infox, section == ideInlayHints)
|
||||
result.version = g.config.suggestVersion
|
||||
result.endLine = endLine
|
||||
result.endCol = endCol
|
||||
|
||||
proc `$`*(suggest: Suggest): string =
|
||||
result = $suggest.section
|
||||
proc `$`*(suggest: SuggestInlayHint): string =
|
||||
result = $suggest.kind
|
||||
result.add(sep)
|
||||
if suggest.section == ideHighlight:
|
||||
if suggest.symkind.TSymKind == skVar and suggest.isGlobal:
|
||||
result.add("skGlobalVar")
|
||||
elif suggest.symkind.TSymKind == skLet and suggest.isGlobal:
|
||||
result.add("skGlobalLet")
|
||||
result.add($suggest.line)
|
||||
result.add(sep)
|
||||
result.add($suggest.column)
|
||||
result.add(sep)
|
||||
result.add(suggest.label)
|
||||
result.add(sep)
|
||||
result.add($suggest.paddingLeft)
|
||||
result.add(sep)
|
||||
result.add($suggest.paddingRight)
|
||||
result.add(sep)
|
||||
result.add($suggest.allowInsert)
|
||||
result.add(sep)
|
||||
result.add(suggest.tooltip)
|
||||
|
||||
proc `$`*(suggest: Suggest): string =
|
||||
if suggest.section == ideInlayHints:
|
||||
result = $suggest.inlayHintInfo
|
||||
else:
|
||||
result = $suggest.section
|
||||
result.add(sep)
|
||||
if suggest.section == ideHighlight:
|
||||
if suggest.symkind.TSymKind == skVar and suggest.isGlobal:
|
||||
result.add("skGlobalVar")
|
||||
elif suggest.symkind.TSymKind == skLet and suggest.isGlobal:
|
||||
result.add("skGlobalLet")
|
||||
else:
|
||||
result.add($suggest.symkind.TSymKind)
|
||||
result.add(sep)
|
||||
result.add($suggest.line)
|
||||
result.add(sep)
|
||||
result.add($suggest.column)
|
||||
result.add(sep)
|
||||
result.add($suggest.tokenLen)
|
||||
else:
|
||||
result.add($suggest.symkind.TSymKind)
|
||||
result.add(sep)
|
||||
result.add($suggest.line)
|
||||
result.add(sep)
|
||||
result.add($suggest.column)
|
||||
result.add(sep)
|
||||
result.add($suggest.tokenLen)
|
||||
else:
|
||||
result.add($suggest.symkind.TSymKind)
|
||||
result.add(sep)
|
||||
if suggest.qualifiedPath.len != 0:
|
||||
result.add(suggest.qualifiedPath.join("."))
|
||||
result.add(sep)
|
||||
result.add(suggest.forth)
|
||||
result.add(sep)
|
||||
result.add(suggest.filePath)
|
||||
result.add(sep)
|
||||
result.add($suggest.line)
|
||||
result.add(sep)
|
||||
result.add($suggest.column)
|
||||
result.add(sep)
|
||||
when defined(nimsuggest) and not defined(noDocgen) and not defined(leanCompiler):
|
||||
result.add(suggest.doc.escape)
|
||||
if suggest.version == 0 or suggest.version == 3:
|
||||
result.add(sep)
|
||||
result.add($suggest.quality)
|
||||
if suggest.section == ideSug:
|
||||
if suggest.qualifiedPath.len != 0:
|
||||
result.add(suggest.qualifiedPath.join("."))
|
||||
result.add(sep)
|
||||
result.add(suggest.forth)
|
||||
result.add(sep)
|
||||
result.add(suggest.filePath)
|
||||
result.add(sep)
|
||||
result.add($suggest.line)
|
||||
result.add(sep)
|
||||
result.add($suggest.column)
|
||||
result.add(sep)
|
||||
when defined(nimsuggest) and not defined(noDocgen) and not defined(leanCompiler):
|
||||
result.add(suggest.doc.escape)
|
||||
if suggest.version == 0 or suggest.version == 3:
|
||||
result.add(sep)
|
||||
result.add($suggest.prefix)
|
||||
result.add($suggest.quality)
|
||||
if suggest.section == ideSug:
|
||||
result.add(sep)
|
||||
result.add($suggest.prefix)
|
||||
|
||||
if (suggest.version == 3 and suggest.section in {ideOutline, ideExpand}):
|
||||
result.add(sep)
|
||||
result.add($suggest.endLine)
|
||||
result.add(sep)
|
||||
result.add($suggest.endCol)
|
||||
if (suggest.version == 3 and suggest.section in {ideOutline, ideExpand}):
|
||||
result.add(sep)
|
||||
result.add($suggest.endLine)
|
||||
result.add(sep)
|
||||
result.add($suggest.endCol)
|
||||
|
||||
proc suggestToSuggestInlayHint*(sug: Suggest): SuggestInlayHint =
|
||||
SuggestInlayHint(
|
||||
kind: sihkType,
|
||||
line: sug.line,
|
||||
column: sug.column + sug.tokenLen,
|
||||
label: ": " & sug.forth,
|
||||
paddingLeft: false,
|
||||
paddingRight: false,
|
||||
allowInsert: true,
|
||||
tooltip: ""
|
||||
)
|
||||
|
||||
proc suggestResult*(conf: ConfigRef; s: Suggest) =
|
||||
if not isNil(conf.suggestionResultHook):
|
||||
@@ -507,7 +553,7 @@ proc findDefinition(g: ModuleGraph; info: TLineInfo; s: PSym; usageSym: var PSym
|
||||
if s.isNil: return
|
||||
if isTracked(info, g.config.m.trackPos, s.name.s.len) or (s == usageSym and sfForward notin s.flags):
|
||||
suggestResult(g.config, symToSuggest(g, s, isLocal=false, ideDef, info, 100, PrefixMatch.None, false, 0, useSuppliedInfo = s == usageSym))
|
||||
if sfForward notin s.flags and g.config.suggestVersion != 3:
|
||||
if sfForward notin s.flags and g.config.suggestVersion < 3:
|
||||
suggestQuit()
|
||||
else:
|
||||
usageSym = s
|
||||
@@ -522,7 +568,7 @@ proc suggestSym*(g: ModuleGraph; info: TLineInfo; s: PSym; usageSym: var PSym; i
|
||||
## misnamed: should be 'symDeclared'
|
||||
let conf = g.config
|
||||
when defined(nimsuggest):
|
||||
g.suggestSymbols.mgetOrPut(info.fileIndex, @[]).add SymInfoPair(sym: s, info: info)
|
||||
g.suggestSymbols.mgetOrPut(info.fileIndex, @[]).add SymInfoPair(sym: s, info: info, isDecl: isDecl)
|
||||
|
||||
if conf.suggestVersion == 0:
|
||||
if s.allUsages.len == 0:
|
||||
@@ -711,7 +757,7 @@ proc suggestSentinel*(c: PContext) =
|
||||
|
||||
when defined(nimsuggest):
|
||||
proc onDef(graph: ModuleGraph, s: PSym, info: TLineInfo) =
|
||||
if graph.config.suggestVersion == 3 and info.exactEquals(s.info):
|
||||
if graph.config.suggestVersion >= 3 and info.exactEquals(s.info):
|
||||
suggestSym(graph, info, s, graph.usageSym)
|
||||
|
||||
template getPContext(): untyped =
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
import
|
||||
intsets, ast, astalgo, trees, msgs, strutils, platform, renderer, options,
|
||||
lineinfos, int128, modulegraphs, astmsgs
|
||||
lineinfos, int128, modulegraphs, astmsgs, wordrecg
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/[assertions, formatfloat]
|
||||
@@ -28,6 +28,8 @@ type
|
||||
preferMixed,
|
||||
# most useful, shows: symbol + resolved symbols if it differs, e.g.:
|
||||
# tuple[a: MyInt{int}, b: float]
|
||||
preferInlayHint,
|
||||
preferInferredEffects,
|
||||
|
||||
TTypeRelation* = enum # order is important!
|
||||
isNone, isConvertible,
|
||||
@@ -508,7 +510,7 @@ const
|
||||
"void", "iterable"]
|
||||
|
||||
const preferToResolveSymbols = {preferName, preferTypeName, preferModuleInfo,
|
||||
preferGenericArg, preferResolved, preferMixed}
|
||||
preferGenericArg, preferResolved, preferMixed, preferInlayHint, preferInferredEffects}
|
||||
|
||||
template bindConcreteTypeToUserTypeClass*(tc, concrete: PType) =
|
||||
tc.add concrete
|
||||
@@ -542,7 +544,10 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||
if prefer in preferToResolveSymbols and t.sym != nil and
|
||||
sfAnon notin t.sym.flags and t.kind != tySequence:
|
||||
if t.kind == tyInt and isIntLit(t):
|
||||
result = t.sym.name.s & " literal(" & $t.n.intVal & ")"
|
||||
if prefer == preferInlayHint:
|
||||
result = t.sym.name.s
|
||||
else:
|
||||
result = t.sym.name.s & " literal(" & $t.n.intVal & ")"
|
||||
elif t.kind == tyAlias and t[0].kind != tyAlias:
|
||||
result = typeToString(t[0])
|
||||
elif prefer in {preferResolved, preferMixed}:
|
||||
@@ -558,7 +563,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||
result = t.sym.name.s
|
||||
if prefer == preferMixed and result != t.sym.name.s:
|
||||
result = t.sym.name.s & "{" & result & "}"
|
||||
elif prefer in {preferName, preferTypeName} or t.sym.owner.isNil:
|
||||
elif prefer in {preferName, preferTypeName, preferInlayHint, preferInferredEffects} or t.sym.owner.isNil:
|
||||
# note: should probably be: {preferName, preferTypeName, preferGenericArg}
|
||||
result = t.sym.name.s
|
||||
if t.kind == tyGenericParam and t.len > 0:
|
||||
@@ -577,8 +582,11 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||
if not isIntLit(t) or prefer == preferExported:
|
||||
result = typeToStr[t.kind]
|
||||
else:
|
||||
if prefer == preferGenericArg:
|
||||
case prefer:
|
||||
of preferGenericArg:
|
||||
result = $t.n.intVal
|
||||
of preferInlayHint:
|
||||
result = "int"
|
||||
else:
|
||||
result = "int literal(" & $t.n.intVal & ")"
|
||||
of tyGenericInst, tyGenericInvocation:
|
||||
@@ -751,12 +759,35 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||
result.add(')')
|
||||
if t.len > 0 and t[0] != nil: result.add(": " & typeToString(t[0]))
|
||||
var prag = if t.callConv == ccNimCall and tfExplicitCallConv notin t.flags: "" else: $t.callConv
|
||||
var hasImplicitRaises = false
|
||||
if not isNil(t.owner) and not isNil(t.owner.ast) and (t.owner.ast.len - 1) >= pragmasPos:
|
||||
let pragmasNode = t.owner.ast[pragmasPos]
|
||||
let raisesSpec = effectSpec(pragmasNode, wRaises)
|
||||
if not isNil(raisesSpec):
|
||||
addSep(prag)
|
||||
prag.add("raises: ")
|
||||
prag.add($raisesSpec)
|
||||
hasImplicitRaises = true
|
||||
if tfNoSideEffect in t.flags:
|
||||
addSep(prag)
|
||||
prag.add("noSideEffect")
|
||||
if tfThread in t.flags:
|
||||
addSep(prag)
|
||||
prag.add("gcsafe")
|
||||
if not hasImplicitRaises and prefer == preferInferredEffects and not isNil(t.owner) and not isNil(t.owner.typ) and not isNil(t.owner.typ.n) and (t.owner.typ.n.len > 0):
|
||||
let effects = t.owner.typ.n[0]
|
||||
if effects.kind == nkEffectList and effects.len == effectListLen:
|
||||
var inferredRaisesStr = ""
|
||||
let effs = effects[exceptionEffects]
|
||||
if not isNil(effs):
|
||||
for eff in items(effs):
|
||||
if not isNil(eff):
|
||||
addSep(inferredRaisesStr)
|
||||
inferredRaisesStr.add($eff.typ)
|
||||
addSep(prag)
|
||||
prag.add("raises: <inferred> [")
|
||||
prag.add(inferredRaisesStr)
|
||||
prag.add("]")
|
||||
if prag.len != 0: result.add("{." & prag & ".}")
|
||||
of tyVarargs:
|
||||
result = typeToStr[t.kind] % typeToString(t[0])
|
||||
@@ -807,11 +838,11 @@ proc firstOrd*(conf: ConfigRef; t: PType): Int128 =
|
||||
result = firstOrd(conf, lastSon(t))
|
||||
of tyOrdinal:
|
||||
if t.len > 0: result = firstOrd(conf, lastSon(t))
|
||||
else: internalError(conf, "invalid kind for firstOrd(" & $t.kind & ')')
|
||||
else: fatal(conf, unknownLineInfo, "invalid kind for firstOrd(" & $t.kind & ')')
|
||||
of tyUncheckedArray, tyCstring:
|
||||
result = Zero
|
||||
else:
|
||||
internalError(conf, "invalid kind for firstOrd(" & $t.kind & ')')
|
||||
fatal(conf, unknownLineInfo, "invalid kind for firstOrd(" & $t.kind & ')')
|
||||
result = Zero
|
||||
|
||||
proc firstFloat*(t: PType): BiggestFloat =
|
||||
@@ -895,11 +926,11 @@ proc lastOrd*(conf: ConfigRef; t: PType): Int128 =
|
||||
of tyProxy: result = Zero
|
||||
of tyOrdinal:
|
||||
if t.len > 0: result = lastOrd(conf, lastSon(t))
|
||||
else: internalError(conf, "invalid kind for lastOrd(" & $t.kind & ')')
|
||||
else: fatal(conf, unknownLineInfo, "invalid kind for lastOrd(" & $t.kind & ')')
|
||||
of tyUncheckedArray:
|
||||
result = Zero
|
||||
else:
|
||||
internalError(conf, "invalid kind for lastOrd(" & $t.kind & ')')
|
||||
fatal(conf, unknownLineInfo, "invalid kind for lastOrd(" & $t.kind & ')')
|
||||
result = Zero
|
||||
|
||||
proc lastFloat*(t: PType): BiggestFloat =
|
||||
|
||||
@@ -811,6 +811,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||
# a[b] = c
|
||||
decodeBC(rkNode)
|
||||
let idx = regs[rb].intVal.int
|
||||
assert regs[ra].kind == rkNode
|
||||
let arr = regs[ra].node
|
||||
case arr.kind
|
||||
of nkTupleConstr: # refer to `opcSlice`
|
||||
@@ -824,7 +825,11 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||
of nkStrKinds:
|
||||
src.strVal[int(realIndex)] = char(regs[rc].intVal)
|
||||
of nkBracket:
|
||||
src[int(realIndex)] = regs[rc].node
|
||||
if regs[rc].kind == rkInt:
|
||||
src[int(realIndex)] = newIntNode(nkIntLit, regs[rc].intVal)
|
||||
else:
|
||||
assert regs[rc].kind == rkNode
|
||||
src[int(realIndex)] = regs[rc].node
|
||||
else:
|
||||
stackTrace(c, tos, pc, "opcWrArr internal error")
|
||||
else:
|
||||
@@ -1015,7 +1020,10 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||
of opcLenCstring:
|
||||
decodeBImm(rkInt)
|
||||
assert regs[rb].kind == rkNode
|
||||
regs[ra].intVal = regs[rb].node.strVal.cstring.len - imm
|
||||
if regs[rb].node.kind == nkNilLit:
|
||||
regs[ra].intVal = -imm
|
||||
else:
|
||||
regs[ra].intVal = regs[rb].node.strVal.cstring.len - imm
|
||||
of opcIncl:
|
||||
decodeB(rkNode)
|
||||
let b = regs[rb].regToNode
|
||||
@@ -1213,6 +1221,12 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||
of opcEqStr:
|
||||
decodeBC(rkInt)
|
||||
regs[ra].intVal = ord(regs[rb].node.strVal == regs[rc].node.strVal)
|
||||
of opcEqCString:
|
||||
decodeBC(rkInt)
|
||||
let bNil = regs[rb].node.kind == nkNilLit
|
||||
let cNil = regs[rc].node.kind == nkNilLit
|
||||
regs[ra].intVal = ord((bNil and cNil) or
|
||||
(not bNil and not cNil and regs[rb].node.strVal == regs[rc].node.strVal))
|
||||
of opcLeStr:
|
||||
decodeBC(rkInt)
|
||||
regs[ra].intVal = ord(regs[rb].node.strVal <= regs[rc].node.strVal)
|
||||
@@ -1496,7 +1510,13 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||
regs[ra].node
|
||||
c.currentExceptionA = raised
|
||||
# Set the `name` field of the exception
|
||||
c.currentExceptionA[2].skipColon.strVal = c.currentExceptionA.typ.sym.name.s
|
||||
var exceptionNameNode = newStrNode(nkStrLit, c.currentExceptionA.typ.sym.name.s)
|
||||
if c.currentExceptionA[2].kind == nkExprColonExpr:
|
||||
exceptionNameNode.typ = c.currentExceptionA[2][1].typ
|
||||
c.currentExceptionA[2][1] = exceptionNameNode
|
||||
else:
|
||||
exceptionNameNode.typ = c.currentExceptionA[2].typ
|
||||
c.currentExceptionA[2] = exceptionNameNode
|
||||
c.exceptionInstr = pc
|
||||
|
||||
var frame = tos
|
||||
|
||||
@@ -99,7 +99,7 @@ type
|
||||
opcLeFloat, opcLtFloat, opcLeu, opcLtu,
|
||||
opcEqRef, opcEqNimNode, opcSameNodeType,
|
||||
opcXor, opcNot, opcUnaryMinusInt, opcUnaryMinusFloat, opcBitnotInt,
|
||||
opcEqStr, opcLeStr, opcLtStr, opcEqSet, opcLeSet, opcLtSet,
|
||||
opcEqStr, opcEqCString, opcLeStr, opcLtStr, opcEqSet, opcLeSet, opcLtSet,
|
||||
opcMulSet, opcPlusSet, opcMinusSet, opcConcatStr,
|
||||
opcContainsSet, opcRepr, opcSetLenStr, opcSetLenSeq,
|
||||
opcIsNil, opcOf, opcIs,
|
||||
|
||||
@@ -406,13 +406,19 @@ proc genIf(c: PCtx, n: PNode; dest: var TDest) =
|
||||
c.gen(it[0], tmp)
|
||||
elsePos = c.xjmp(it[0], opcFJmp, tmp) # if false
|
||||
c.clearDest(n, dest)
|
||||
c.gen(it[1], dest) # then part
|
||||
if isEmptyType(it[1].typ): # maybe noreturn call, don't touch `dest`
|
||||
c.gen(it[1])
|
||||
else:
|
||||
c.gen(it[1], dest) # then part
|
||||
if i < n.len-1:
|
||||
endings.add(c.xjmp(it[1], opcJmp, 0))
|
||||
c.patch(elsePos)
|
||||
else:
|
||||
c.clearDest(n, dest)
|
||||
c.gen(it[0], dest)
|
||||
if isEmptyType(it[0].typ): # maybe noreturn call, don't touch `dest`
|
||||
c.gen(it[0])
|
||||
else:
|
||||
c.gen(it[0], dest)
|
||||
for endPos in endings: c.patch(endPos)
|
||||
c.clearDest(n, dest)
|
||||
|
||||
@@ -506,17 +512,25 @@ proc genCase(c: PCtx; n: PNode; dest: var TDest) =
|
||||
let it = n[i]
|
||||
if it.len == 1:
|
||||
# else stmt:
|
||||
if it[0].kind != nkNilLit or it[0].typ != nil:
|
||||
let body = it[0]
|
||||
if body.kind != nkNilLit or body.typ != nil:
|
||||
# an nkNilLit with nil for typ implies there is no else branch, this
|
||||
# avoids unused related errors as we've already consumed the dest
|
||||
c.gen(it[0], dest)
|
||||
if isEmptyType(body.typ): # maybe noreturn call, don't touch `dest`
|
||||
c.gen(body)
|
||||
else:
|
||||
c.gen(body, dest)
|
||||
else:
|
||||
let b = rawGenLiteral(c, it)
|
||||
c.gABx(it, opcBranch, tmp, b)
|
||||
let elsePos = c.xjmp(it.lastSon, opcFJmp, tmp)
|
||||
c.gen(it.lastSon, dest)
|
||||
let body = it.lastSon
|
||||
let elsePos = c.xjmp(body, opcFJmp, tmp)
|
||||
if isEmptyType(body.typ): # maybe noreturn call, don't touch `dest`
|
||||
c.gen(body)
|
||||
else:
|
||||
c.gen(body, dest)
|
||||
if i < n.len-1:
|
||||
endings.add(c.xjmp(it.lastSon, opcJmp, 0))
|
||||
endings.add(c.xjmp(body, opcJmp, 0))
|
||||
c.patch(elsePos)
|
||||
c.clearDest(n, dest)
|
||||
for endPos in endings: c.patch(endPos)
|
||||
@@ -532,7 +546,10 @@ proc genTry(c: PCtx; n: PNode; dest: var TDest) =
|
||||
if dest < 0 and not isEmptyType(n.typ): dest = getTemp(c, n.typ)
|
||||
var endings: seq[TPosition] = @[]
|
||||
let ehPos = c.xjmp(n, opcTry, 0)
|
||||
c.gen(n[0], dest)
|
||||
if isEmptyType(n[0].typ): # maybe noreturn call, don't touch `dest`
|
||||
c.gen(n[0])
|
||||
else:
|
||||
c.gen(n[0], dest)
|
||||
c.clearDest(n, dest)
|
||||
# Add a jump past the exception handling code
|
||||
let jumpToFinally = c.xjmp(n, opcJmp, 0)
|
||||
@@ -550,7 +567,11 @@ proc genTry(c: PCtx; n: PNode; dest: var TDest) =
|
||||
if it.len == 1:
|
||||
# general except section:
|
||||
c.gABx(it, opcExcept, 0, 0)
|
||||
c.gen(it.lastSon, dest)
|
||||
let body = it.lastSon
|
||||
if isEmptyType(body.typ): # maybe noreturn call, don't touch `dest`
|
||||
c.gen(body)
|
||||
else:
|
||||
c.gen(body, dest)
|
||||
c.clearDest(n, dest)
|
||||
if i < n.len:
|
||||
endings.add(c.xjmp(it, opcJmp, 0))
|
||||
@@ -882,6 +903,8 @@ proc genCastIntFloat(c: PCtx; n: PNode; dest: var TDest) =
|
||||
let dst = n[0].typ.skipTypes(abstractRange)#.kind
|
||||
let srcSize = getSize(c.config, src)
|
||||
let dstSize = getSize(c.config, dst)
|
||||
const unsupportedCastDifferentSize =
|
||||
"VM does not support 'cast' from $1 with size $2 to $3 with size $4 due to different sizes"
|
||||
if src.kind in allowedIntegers and dst.kind in allowedIntegers:
|
||||
let tmp = c.genx(n[1])
|
||||
if dest < 0: dest = c.getTemp(n[0].typ)
|
||||
@@ -898,8 +921,11 @@ proc genCastIntFloat(c: PCtx; n: PNode; dest: var TDest) =
|
||||
# is smaller than source.
|
||||
c.gABC(n, opcNarrowU, dest, TRegister(dstSize*8))
|
||||
c.freeTemp(tmp)
|
||||
elif srcSize == dstSize and src.kind in allowedIntegers and
|
||||
dst.kind in {tyFloat, tyFloat32, tyFloat64}:
|
||||
elif src.kind in allowedIntegers and
|
||||
dst.kind in {tyFloat, tyFloat32, tyFloat64}:
|
||||
if srcSize != dstSize:
|
||||
globalError(c.config, n.info, unsupportedCastDifferentSize %
|
||||
[$src.kind, $srcSize, $dst.kind, $dstSize])
|
||||
let tmp = c.genx(n[1])
|
||||
if dest < 0: dest = c.getTemp(n[0].typ)
|
||||
if dst.kind == tyFloat32:
|
||||
@@ -908,8 +934,11 @@ proc genCastIntFloat(c: PCtx; n: PNode; dest: var TDest) =
|
||||
c.gABC(n, opcCastIntToFloat64, dest, tmp)
|
||||
c.freeTemp(tmp)
|
||||
|
||||
elif srcSize == dstSize and src.kind in {tyFloat, tyFloat32, tyFloat64} and
|
||||
elif src.kind in {tyFloat, tyFloat32, tyFloat64} and
|
||||
dst.kind in allowedIntegers:
|
||||
if srcSize != dstSize:
|
||||
globalError(c.config, n.info, unsupportedCastDifferentSize %
|
||||
[$src.kind, $srcSize, $dst.kind, $dstSize])
|
||||
let tmp = c.genx(n[1])
|
||||
if dest < 0: dest = c.getTemp(n[0].typ)
|
||||
if src.kind == tyFloat32:
|
||||
@@ -1151,7 +1180,8 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
|
||||
c.gABC(n, opcNarrowU, dest, TRegister(size*8))
|
||||
of mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr, mFloatToStr, mCStrToStr, mStrToStr, mEnumToStr:
|
||||
genConv(c, n, n[1], dest)
|
||||
of mEqStr, mEqCString: genBinaryABC(c, n, dest, opcEqStr)
|
||||
of mEqStr: genBinaryABC(c, n, dest, opcEqStr)
|
||||
of mEqCString: genBinaryABC(c, n, dest, opcEqCString)
|
||||
of mLeStr: genBinaryABC(c, n, dest, opcLeStr)
|
||||
of mLtStr: genBinaryABC(c, n, dest, opcLtStr)
|
||||
of mEqSet: genBinarySet(c, n, dest, opcEqSet)
|
||||
@@ -1525,6 +1555,7 @@ proc checkCanEval(c: PCtx; n: PNode) =
|
||||
# little hack ahead for bug #12612: assume gensym'ed variables
|
||||
# are in the right scope:
|
||||
if sfGenSym in s.flags and c.prc.sym == nil: discard
|
||||
elif s.kind == skParam and s.typ.kind == tyTypeDesc: discard
|
||||
else: cannotEval(c, n)
|
||||
elif s.kind in {skProc, skFunc, skConverter, skMethod,
|
||||
skIterator} and sfForward in s.flags:
|
||||
@@ -1864,10 +1895,10 @@ proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode =
|
||||
result = newNodeIT(nkUIntLit, info, t)
|
||||
of tyFloat..tyFloat128:
|
||||
result = newNodeIT(nkFloatLit, info, t)
|
||||
of tyCstring, tyString:
|
||||
of tyString:
|
||||
result = newNodeIT(nkStrLit, info, t)
|
||||
result.strVal = ""
|
||||
of tyVar, tyLent, tyPointer, tyPtr, tyUntyped,
|
||||
of tyCstring, tyVar, tyLent, tyPointer, tyPtr, tyUntyped,
|
||||
tyTyped, tyTypeDesc, tyRef, tyNil:
|
||||
result = newNodeIT(nkNilLit, info, t)
|
||||
of tyProc:
|
||||
@@ -2079,8 +2110,13 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
|
||||
let s = n.sym
|
||||
checkCanEval(c, n)
|
||||
case s.kind
|
||||
of skVar, skForVar, skTemp, skLet, skParam, skResult:
|
||||
of skVar, skForVar, skTemp, skLet, skResult:
|
||||
genRdVar(c, n, dest, flags)
|
||||
of skParam:
|
||||
if s.typ.kind == tyTypeDesc:
|
||||
genTypeLit(c, s.typ.skipTypes({tyTypeDesc}), dest)
|
||||
else:
|
||||
genRdVar(c, n, dest, flags)
|
||||
of skProc, skFunc, skConverter, skMacro, skTemplate, skMethod, skIterator:
|
||||
# 'skTemplate' is only allowed for 'getAst' support:
|
||||
if s.kind == skIterator and s.typ.callConv == TCallingConvention.ccClosure:
|
||||
|
||||
@@ -237,10 +237,10 @@ doc.file = """<?xml version="1.0" encoding="utf-8" ?>
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4QQQEwksSS9ZWwAAAk1JREFUWMPtll2ITVEUx39nn/O7Y5qR8f05wtCUUr6ZIS++8pEnkZInPImneaCQ5METNdOkeFBKUhMPRIkHKfEuUZSUlGlKPN2TrgfncpvmnntnmlEyq1Z7t89/rf9a6+y99oZxGZf/XeIq61EdtgKXgdXA0xrYAvBjOIF1AI9zvjcC74BSpndrJPkBWDScTF8Aa4E3wDlgHbASaANmVqlcCnwHvgDvgVfAJ+AikAAvgfVZwLnSVZHZaOuKoQi3ZOMi4NkYkpe1p4J7A8BpYAD49hfIy/oqG0+hLomiKP2L5L+1ubn5115S+3OAn4EnwBlgMzCjyt6ZAnQCJ4A7wOs88iRJHvw50HoujuPBoCKwHWiosy8MdfZnAdcHk8dxXFJ3VQbQlCTJvRBCGdRbD4M6uc5glpY3eAihpN5S5w12diSEcCCEcKUO4ljdr15T76ur1FDDLIQQ3qv71EdDOe3Kxj3leRXyk+pxdWnFWod6Wt2bY3de3aSuUHcPBVimHs7mK9WrmeOF6lR1o9qnzskh2ar2qm1qizpfXaPeVGdlmGN5pb09qMxz1Xb1kLqgzn1RyH7JUXW52lr5e/Kqi9qpto7V1atuUzfnARrV7jEib1T76gG2qxdGmXyiekkt1GswPTtek0aBfJp6YySGBfWg2tPQ0FAYgf1stUfdmdcjarbYJEniKIq6gY/Aw+zWHAC+p2labGpqiorFYgGYCEzN7oQdQClN07O1/EfDyGgC0ALMBdYAi4FyK+4H3gLPsxfR1zRNi+NP7nH5J+QntnXe5B5mpfQAAAAASUVORK5CYII=">
|
||||
|
||||
<!-- CSS -->
|
||||
<link rel="stylesheet" type="text/css" href="$nimdoccss">
|
||||
<link rel="stylesheet" type="text/css" href="${nimdoccss}?v=$nimVersion">
|
||||
|
||||
<!-- JS -->
|
||||
<script type="text/javascript" src="$dochackjs"></script>
|
||||
<script type="text/javascript" src="${dochackjs}?v=$nimVersion"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="documentId">
|
||||
|
||||
@@ -217,9 +217,11 @@ type
|
||||
## code.
|
||||
|
||||
proc destroyRegex(pattern: Regex) =
|
||||
`=destroy`(pattern.pattern)
|
||||
pcre.free_substring(cast[cstring](pattern.pcreObj))
|
||||
if pattern.pcreExtra != nil:
|
||||
pcre.free_study(pattern.pcreExtra)
|
||||
`=destroy`(pattern.captureNameToId)
|
||||
|
||||
proc getinfo[T](pattern: Regex, opt: cint): T =
|
||||
let retcode = pcre.fullinfo(pattern.pcreObj, pattern.pcreExtra, opt, addr result)
|
||||
|
||||
@@ -465,6 +465,7 @@ const MSG_EOR* = cint(128)
|
||||
const MSG_OOB* = cint(1)
|
||||
const SCM_RIGHTS* = cint(1)
|
||||
const SO_ACCEPTCONN* = cint(30)
|
||||
const SO_BINDTODEVICE* = cint(25)
|
||||
const SO_BROADCAST* = cint(6)
|
||||
const SO_DEBUG* = cint(1)
|
||||
const SO_DONTROUTE* = cint(5)
|
||||
|
||||
@@ -606,10 +606,10 @@ when not defined(lwip):
|
||||
|
||||
when defined(zephyr):
|
||||
type
|
||||
Tnfds* = distinct cint
|
||||
Tnfds* = distinct culong
|
||||
else:
|
||||
type
|
||||
Tnfds* {.importc: "nfds_t", header: "<poll.h>".} = cint
|
||||
Tnfds* {.importc: "nfds_t", header: "<poll.h>".} = culong
|
||||
|
||||
var
|
||||
errno* {.importc, header: "<errno.h>".}: cint ## error variable
|
||||
|
||||
@@ -482,6 +482,7 @@ var MSG_EOR* {.importc: "MSG_EOR", header: "<sys/socket.h>".}: cint
|
||||
var MSG_OOB* {.importc: "MSG_OOB", header: "<sys/socket.h>".}: cint
|
||||
var SCM_RIGHTS* {.importc: "SCM_RIGHTS", header: "<sys/socket.h>".}: cint
|
||||
var SO_ACCEPTCONN* {.importc: "SO_ACCEPTCONN", header: "<sys/socket.h>".}: cint
|
||||
var SO_BINDTODEVICE* {.importc: "SO_BINDTODEVICE", header: "<sys/socket.h>".}: cint
|
||||
var SO_BROADCAST* {.importc: "SO_BROADCAST", header: "<sys/socket.h>".}: cint
|
||||
var SO_DEBUG* {.importc: "SO_DEBUG", header: "<sys/socket.h>".}: cint
|
||||
var SO_DONTROUTE* {.importc: "SO_DONTROUTE", header: "<sys/socket.h>".}: cint
|
||||
|
||||
@@ -66,14 +66,10 @@ template cbBase(a, b): untyped = [
|
||||
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', a, b]
|
||||
|
||||
let
|
||||
const
|
||||
cb64 = cbBase('+', '/')
|
||||
cb64safe = cbBase('-', '_')
|
||||
|
||||
const
|
||||
cb64VM = cbBase('+', '/')
|
||||
cb64safeVM = cbBase('-', '_')
|
||||
|
||||
const
|
||||
invalidChar = 255
|
||||
|
||||
@@ -134,14 +130,10 @@ template encodeInternal(s, alphabet: typed): untyped =
|
||||
result.setLen(outputIndex)
|
||||
|
||||
template encodeImpl() {.dirty.} =
|
||||
when nimvm:
|
||||
block:
|
||||
let lookupTableVM = if safe: cb64safeVM else: cb64VM
|
||||
encodeInternal(s, lookupTableVM)
|
||||
if safe:
|
||||
encodeInternal(s, cb64safe)
|
||||
else:
|
||||
block:
|
||||
let lookupTable = if safe: unsafeAddr(cb64safe) else: unsafeAddr(cb64)
|
||||
encodeInternal(s, lookupTable)
|
||||
encodeInternal(s, cb64)
|
||||
|
||||
proc encode*[T: byte|char](s: openArray[T], safe = false): string =
|
||||
## Encodes `s` into base64 representation.
|
||||
|
||||
@@ -165,28 +165,6 @@ proc newSinglyLinkedNode*[T](value: T): SinglyLinkedNode[T] =
|
||||
new(result)
|
||||
result.value = value
|
||||
|
||||
func toSinglyLinkedList*[T](elems: openArray[T]): SinglyLinkedList[T] {.since: (1, 5, 1).} =
|
||||
## Creates a new `SinglyLinkedList` from the members of `elems`.
|
||||
runnableExamples:
|
||||
from std/sequtils import toSeq
|
||||
let a = [1, 2, 3, 4, 5].toSinglyLinkedList
|
||||
assert a.toSeq == [1, 2, 3, 4, 5]
|
||||
|
||||
result = initSinglyLinkedList[T]()
|
||||
for elem in elems.items:
|
||||
result.add(elem)
|
||||
|
||||
func toDoublyLinkedList*[T](elems: openArray[T]): DoublyLinkedList[T] {.since: (1, 5, 1).} =
|
||||
## Creates a new `DoublyLinkedList` from the members of `elems`.
|
||||
runnableExamples:
|
||||
from std/sequtils import toSeq
|
||||
let a = [1, 2, 3, 4, 5].toDoublyLinkedList
|
||||
assert a.toSeq == [1, 2, 3, 4, 5]
|
||||
|
||||
result = initDoublyLinkedList[T]()
|
||||
for elem in elems.items:
|
||||
result.add(elem)
|
||||
|
||||
template itemsListImpl() {.dirty.} =
|
||||
var it {.cursor.} = L.head
|
||||
while it != nil:
|
||||
@@ -993,3 +971,25 @@ proc appendMoved*[T: SomeLinkedList](a, b: var T) {.since: (1, 5, 1).} =
|
||||
## * `addMoved proc <#addMoved,SinglyLinkedList[T],SinglyLinkedList[T]>`_
|
||||
## * `addMoved proc <#addMoved,DoublyLinkedList[T],DoublyLinkedList[T]>`_
|
||||
a.addMoved(b)
|
||||
|
||||
func toSinglyLinkedList*[T](elems: openArray[T]): SinglyLinkedList[T] {.since: (1, 5, 1).} =
|
||||
## Creates a new `SinglyLinkedList` from the members of `elems`.
|
||||
runnableExamples:
|
||||
from std/sequtils import toSeq
|
||||
let a = [1, 2, 3, 4, 5].toSinglyLinkedList
|
||||
assert a.toSeq == [1, 2, 3, 4, 5]
|
||||
|
||||
result = initSinglyLinkedList[T]()
|
||||
for elem in elems.items:
|
||||
result.add(elem)
|
||||
|
||||
func toDoublyLinkedList*[T](elems: openArray[T]): DoublyLinkedList[T] {.since: (1, 5, 1).} =
|
||||
## Creates a new `DoublyLinkedList` from the members of `elems`.
|
||||
runnableExamples:
|
||||
from std/sequtils import toSeq
|
||||
let a = [1, 2, 3, 4, 5].toDoublyLinkedList
|
||||
assert a.toSeq == [1, 2, 3, 4, 5]
|
||||
|
||||
result = initDoublyLinkedList[T]()
|
||||
for elem in elems.items:
|
||||
result.add(elem)
|
||||
|
||||
@@ -200,8 +200,8 @@ const
|
||||
colGoldenRod* = Color(0xDAA520)
|
||||
colGray* = Color(0x808080)
|
||||
colGreen* = Color(0x008000)
|
||||
colGrey* = Color(0x808080)
|
||||
colGreenYellow* = Color(0xADFF2F)
|
||||
colGrey* = Color(0x808080)
|
||||
colHoneyDew* = Color(0xF0FFF0)
|
||||
colHotPink* = Color(0xFF69B4)
|
||||
colIndianRed* = Color(0xCD5C5C)
|
||||
@@ -350,8 +350,8 @@ const
|
||||
"goldenrod": colGoldenRod,
|
||||
"gray": colGray,
|
||||
"green": colGreen,
|
||||
"grey": colGrey,
|
||||
"greenyellow": colGreenYellow,
|
||||
"grey": colGrey,
|
||||
"honeydew": colHoneyDew,
|
||||
"hotpink": colHotPink,
|
||||
"indianred": colIndianRed,
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
{.deprecated: "use the nimble packages `malebolgia`, `taskpools` or `weave` instead".}
|
||||
|
||||
## Implements Nim's `parallel & spawn statements <manual_experimental.html#parallel-amp-spawn>`_.
|
||||
##
|
||||
## Unstable API.
|
||||
|
||||
@@ -319,16 +319,24 @@ proc murmurHash(x: openArray[byte]): Hash =
|
||||
h1: uint32
|
||||
i = 0
|
||||
|
||||
|
||||
template impl =
|
||||
var j = stepSize
|
||||
while j > 0:
|
||||
dec j
|
||||
k1 = (k1 shl 8) or (ord(x[i+j])).uint32
|
||||
|
||||
# body
|
||||
while i < n * stepSize:
|
||||
var k1: uint32
|
||||
when defined(js) or defined(sparc) or defined(sparc64):
|
||||
var j = stepSize
|
||||
while j > 0:
|
||||
dec j
|
||||
k1 = (k1 shl 8) or (ord(x[i+j])).uint32
|
||||
|
||||
when nimvm:
|
||||
impl()
|
||||
else:
|
||||
k1 = cast[ptr uint32](unsafeAddr x[i])[]
|
||||
when declared(copyMem):
|
||||
copyMem(addr k1, addr x[i], 4)
|
||||
else:
|
||||
impl()
|
||||
inc i, stepSize
|
||||
|
||||
k1 = imul(k1, c1)
|
||||
|
||||
@@ -387,21 +387,37 @@ when not useNimNetLite:
|
||||
|
||||
proc getHostByAddr*(ip: string): Hostent {.tags: [ReadIOEffect].} =
|
||||
## This function will lookup the hostname of an IP Address.
|
||||
var myaddr: InAddr
|
||||
myaddr.s_addr = inet_addr(ip)
|
||||
var
|
||||
addrInfo = getAddrInfo(ip, Port(0), AF_UNSPEC)
|
||||
myAddr: pointer
|
||||
addrLen = 0
|
||||
family = 0
|
||||
|
||||
defer: freeAddrInfo(addrInfo)
|
||||
|
||||
if addrInfo.ai_addr.sa_family.cint == nativeAfInet:
|
||||
family = nativeAfInet
|
||||
myAddr = addr cast[ptr Sockaddr_in](addrInfo.ai_addr).sin_addr
|
||||
addrLen = 4
|
||||
elif addrInfo.ai_addr.sa_family.cint == nativeAfInet6:
|
||||
family = nativeAfInet6
|
||||
myAddr = addr cast[ptr Sockaddr_in6](addrInfo.ai_addr).sin6_addr
|
||||
addrLen = 16
|
||||
else:
|
||||
raise newException(IOError, "Unknown socket family in `getHostByAddr()`")
|
||||
|
||||
when useWinVersion:
|
||||
var s = winlean.gethostbyaddr(addr(myaddr), sizeof(myaddr).cuint,
|
||||
cint(AF_INET))
|
||||
var s = winlean.gethostbyaddr(cast[ptr InAddr](myAddr), addrLen.cuint,
|
||||
cint(family))
|
||||
if s == nil: raiseOSError(osLastError())
|
||||
else:
|
||||
var s =
|
||||
when defined(android4):
|
||||
posix.gethostbyaddr(cast[cstring](addr(myaddr)), sizeof(myaddr).cint,
|
||||
cint(posix.AF_INET))
|
||||
posix.gethostbyaddr(cast[cstring](myAddr), addrLen.cint,
|
||||
cint(family))
|
||||
else:
|
||||
posix.gethostbyaddr(addr(myaddr), sizeof(myaddr).SockLen,
|
||||
cint(posix.AF_INET))
|
||||
posix.gethostbyaddr(myAddr, addrLen.SockLen,
|
||||
cint(family))
|
||||
if s == nil:
|
||||
raiseOSError(osLastError(), $hstrerror(h_errno))
|
||||
|
||||
@@ -424,7 +440,20 @@ when not useNimNetLite:
|
||||
result.addrList.add($inet_ntoa(inaddrPtr[]))
|
||||
inc(i)
|
||||
else:
|
||||
result.addrList = cstringArrayToSeq(s.h_addr_list)
|
||||
let strAddrLen = when not useWinVersion: posix.INET6_ADDRSTRLEN.int
|
||||
else: 46
|
||||
var i = 0
|
||||
while not isNil(s.h_addr_list[i]):
|
||||
var ipStr = newString(strAddrLen)
|
||||
if inet_ntop(nativeAfInet6, cast[pointer](s.h_addr_list[i]),
|
||||
cstring(ipStr), len(ipStr).int32) == nil:
|
||||
raiseOSError(osLastError())
|
||||
when not useWinVersion:
|
||||
if posix.IN6_IS_ADDR_V4MAPPED(cast[ptr In6Addr](s.h_addr_list[i])) != 0:
|
||||
ipStr.setSlice("::ffff:".len..<strAddrLen)
|
||||
setLen(ipStr, len(cstring(ipStr)))
|
||||
result.addrList.add(ipStr)
|
||||
inc(i)
|
||||
result.length = int(s.h_length)
|
||||
|
||||
proc getHostByName*(name: string): Hostent {.tags: [ReadIOEffect].} =
|
||||
|
||||
@@ -638,14 +638,14 @@ proc getAppFilename*(): string {.rtl, extern: "nos$1", tags: [ReadIOEffect], noW
|
||||
# /proc/<pid>/path/a.out (complete pathname)
|
||||
when defined(windows):
|
||||
var bufsize = int32(MAX_PATH)
|
||||
var buf = newWideCString("", bufsize)
|
||||
var buf = newWideCString(bufsize)
|
||||
while true:
|
||||
var L = getModuleFileNameW(0, buf, bufsize)
|
||||
if L == 0'i32:
|
||||
result = "" # error!
|
||||
break
|
||||
elif L > bufsize:
|
||||
buf = newWideCString("", L)
|
||||
buf = newWideCString(L)
|
||||
bufsize = L
|
||||
else:
|
||||
result = buf$L
|
||||
|
||||
@@ -562,7 +562,7 @@ template matchOrParse(mopProc: untyped) =
|
||||
# procs. For the former, *enter* and *leave* event handler code generators
|
||||
# are provided which just return *discard*.
|
||||
|
||||
proc mopProc(s: string, p: Peg, start: int, c: var Captures): int {.gcsafe.} =
|
||||
proc mopProc(s: string, p: Peg, start: int, c: var Captures): int {.gcsafe, raises: [].} =
|
||||
proc matchBackRef(s: string, p: Peg, start: int, c: var Captures): int =
|
||||
# Parse handler code must run in an *of* clause of its own for each
|
||||
# *PegKind*, so we encapsulate the identical clause body for
|
||||
|
||||
@@ -457,10 +457,6 @@ when not defined(js) and not defined(nimSeqsV2):
|
||||
data: UncheckedArray[char]
|
||||
NimString = ptr NimStringDesc
|
||||
|
||||
when notJSnotNims and not defined(nimSeqsV2):
|
||||
template space(s: PGenericSeq): int {.dirty.} =
|
||||
s.reserved and not (seqShallowFlag or strlitFlag)
|
||||
|
||||
when notJSnotNims:
|
||||
include "system/hti"
|
||||
|
||||
@@ -1068,6 +1064,10 @@ const
|
||||
hasThreadSupport = compileOption("threads") and not defined(nimscript)
|
||||
hasSharedHeap = defined(boehmgc) or defined(gogc) # don't share heaps; every thread has its own
|
||||
|
||||
when notJSnotNims and not defined(nimSeqsV2):
|
||||
template space(s: PGenericSeq): int =
|
||||
s.reserved and not (seqShallowFlag or strlitFlag)
|
||||
|
||||
when hasThreadSupport and defined(tcc) and not compileOption("tlsEmulation"):
|
||||
# tcc doesn't support TLS
|
||||
{.error: "`--tlsEmulation:on` must be used when using threads with tcc backend".}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
const
|
||||
NimMajor* {.intdefine.}: int = 1
|
||||
NimMajor* {.intdefine.}: int = 2
|
||||
## is the major number of Nim's version. Example:
|
||||
## ```
|
||||
## when (NimMajor, NimMinor, NimPatch) >= (1, 3, 1): discard
|
||||
## ```
|
||||
# see also std/private/since
|
||||
|
||||
NimMinor* {.intdefine.}: int = 9
|
||||
NimMinor* {.intdefine.}: int = 0
|
||||
## is the minor number of Nim's version.
|
||||
## Odd for devel, even for releases.
|
||||
|
||||
NimPatch* {.intdefine.}: int = 5
|
||||
NimPatch* {.intdefine.}: int = 4
|
||||
## is the patch number of Nim's version.
|
||||
## Odd for devel, even for releases.
|
||||
|
||||
@@ -144,16 +144,17 @@ template currentSourcePath*: string = instantiationInfo(-1, true).filename
|
||||
## Returns the full file-system path of the current source.
|
||||
##
|
||||
## To get the directory containing the current source, use it with
|
||||
## `os.parentDir() <os.html#parentDir%2Cstring>`_ as `currentSourcePath.parentDir()`.
|
||||
## `ospaths2.parentDir() <ospaths2.html#parentDir%2Cstring>`_ as
|
||||
## `currentSourcePath.parentDir()`.
|
||||
##
|
||||
## The path returned by this template is set at compile time.
|
||||
##
|
||||
## See the docstring of `macros.getProjectPath() <macros.html#getProjectPath>`_
|
||||
## for an example to see the distinction between the `currentSourcePath`
|
||||
## and `getProjectPath`.
|
||||
## for an example to see the distinction between the `currentSourcePath()`
|
||||
## and `getProjectPath()`.
|
||||
##
|
||||
## See also:
|
||||
## * `getCurrentDir proc <os.html#getCurrentDir>`_
|
||||
## * `ospaths2.getCurrentDir() proc <ospaths2.html#getCurrentDir>`_
|
||||
|
||||
proc slurp*(filename: string): string {.magic: "Slurp".}
|
||||
## This is an alias for `staticRead <#staticRead,string>`_.
|
||||
|
||||
@@ -278,7 +278,9 @@ proc toJSStr(s: string): cstring {.compilerproc.} =
|
||||
|
||||
proc mnewString(len: int): string {.asmNoStackFrame, compilerproc.} =
|
||||
asm """
|
||||
return new Array(`len`);
|
||||
var result = new Array(`len`);
|
||||
for (var i = 0; i < `len`; i++) {result[i] = 0;}
|
||||
return result;
|
||||
"""
|
||||
|
||||
proc SetCard(a: int): int {.compilerproc, asmNoStackFrame.} =
|
||||
|
||||
@@ -88,7 +88,7 @@ type
|
||||
|
||||
proc alloc(r: var MemRegion, size: int): pointer =
|
||||
result = alloc(size)
|
||||
proc alloc0Impl(r: var MemRegion, size: int): pointer =
|
||||
proc alloc0(r: var MemRegion, size: int): pointer =
|
||||
result = alloc0Impl(size)
|
||||
proc dealloc(r: var MemRegion, p: pointer) = dealloc(p)
|
||||
proc deallocOsPages(r: var MemRegion) = discard
|
||||
|
||||
@@ -140,8 +140,6 @@ proc newSeq[T](s: var seq[T], len: Natural) =
|
||||
setLen(s, len)
|
||||
|
||||
|
||||
template capacityImpl(sek: NimSeqV2): int =
|
||||
if sek.p != nil: (xu.p.cap and not strlitFlag) else: 0
|
||||
|
||||
func capacity*[T](self: seq[T]): int {.inline.} =
|
||||
## Returns the current capacity of the seq.
|
||||
@@ -151,9 +149,8 @@ func capacity*[T](self: seq[T]): int {.inline.} =
|
||||
lst.add "Nim"
|
||||
assert lst.capacity == 42
|
||||
|
||||
{.cast(noSideEffect).}:
|
||||
let sek = unsafeAddr self
|
||||
result = capacityImpl(cast[ptr NimSeqV2](sek)[])
|
||||
let sek = cast[ptr NimSeqV2[T]](unsafeAddr self)
|
||||
result = if sek.p != nil: sek.p.cap and not strlitFlag else: 0
|
||||
|
||||
|
||||
{.pop.} # See https://github.com/nim-lang/Nim/issues/21401
|
||||
|
||||
@@ -13,9 +13,11 @@
|
||||
proc cardSetImpl(s: ptr UncheckedArray[uint8], len: int): int {.inline.} =
|
||||
var i = 0
|
||||
result = 0
|
||||
var num = 0'u64
|
||||
when defined(x86) or defined(amd64):
|
||||
while i < len - 8:
|
||||
inc(result, countBits64((cast[ptr uint64](s[i].unsafeAddr))[]))
|
||||
copyMem(addr num, addr s[i], 8)
|
||||
inc(result, countBits64(num))
|
||||
inc(i, 8)
|
||||
|
||||
while i < len:
|
||||
|
||||
@@ -34,53 +34,72 @@ template frees(s) =
|
||||
else:
|
||||
dealloc(s.p)
|
||||
|
||||
template allocPayload(newLen: int): ptr NimStrPayload =
|
||||
when compileOption("threads"):
|
||||
cast[ptr NimStrPayload](allocShared(contentSize(newLen)))
|
||||
else:
|
||||
cast[ptr NimStrPayload](alloc(contentSize(newLen)))
|
||||
|
||||
template allocPayload0(newLen: int): ptr NimStrPayload =
|
||||
when compileOption("threads"):
|
||||
cast[ptr NimStrPayload](allocShared0(contentSize(newLen)))
|
||||
else:
|
||||
cast[ptr NimStrPayload](alloc0(contentSize(newLen)))
|
||||
|
||||
template reallocPayload(p: pointer, newLen: int): ptr NimStrPayload =
|
||||
when compileOption("threads"):
|
||||
cast[ptr NimStrPayload](reallocShared(p, contentSize(newLen)))
|
||||
else:
|
||||
cast[ptr NimStrPayload](realloc(p, contentSize(newLen)))
|
||||
|
||||
template reallocPayload0(p: pointer; oldLen, newLen: int): ptr NimStrPayload =
|
||||
when compileOption("threads"):
|
||||
cast[ptr NimStrPayload](reallocShared0(p, contentSize(oldLen), contentSize(newLen)))
|
||||
else:
|
||||
cast[ptr NimStrPayload](realloc0(p, contentSize(oldLen), contentSize(newLen)))
|
||||
|
||||
proc resize(old: int): int {.inline.} =
|
||||
if old <= 0: result = 4
|
||||
elif old <= high(int16): result = old * 2
|
||||
else: result = old * 3 div 2 # for large arrays * 3/2 is better
|
||||
|
||||
proc prepareAdd(s: var NimStringV2; addlen: int) {.compilerRtl.} =
|
||||
let newLen = s.len + addlen
|
||||
proc prepareAdd(s: var NimStringV2; addLen: int) {.compilerRtl.} =
|
||||
let newLen = s.len + addLen
|
||||
if isLiteral(s):
|
||||
let oldP = s.p
|
||||
# can't mutate a literal, so we need a fresh copy here:
|
||||
when compileOption("threads"):
|
||||
s.p = cast[ptr NimStrPayload](allocShared0(contentSize(newLen)))
|
||||
else:
|
||||
s.p = cast[ptr NimStrPayload](alloc0(contentSize(newLen)))
|
||||
s.p = allocPayload(newLen)
|
||||
s.p.cap = newLen
|
||||
if s.len > 0:
|
||||
# we are about to append, so there is no need to copy the \0 terminator:
|
||||
copyMem(unsafeAddr s.p.data[0], unsafeAddr oldP.data[0], min(s.len, newLen))
|
||||
elif oldP == nil:
|
||||
# In the case of `newString(0) & ""`, since `src.len == 0`, `appendString`
|
||||
# will not set the `\0` terminator, so we set it here.
|
||||
s.p.data[0] = '\0'
|
||||
else:
|
||||
let oldCap = s.p.cap and not strlitFlag
|
||||
if newLen > oldCap:
|
||||
let newCap = max(newLen, resize(oldCap))
|
||||
when compileOption("threads"):
|
||||
s.p = cast[ptr NimStrPayload](reallocShared0(s.p, contentSize(oldCap), contentSize(newCap)))
|
||||
else:
|
||||
s.p = cast[ptr NimStrPayload](realloc0(s.p, contentSize(oldCap), contentSize(newCap)))
|
||||
s.p = reallocPayload(s.p, newCap)
|
||||
s.p.cap = newCap
|
||||
if newLen < newCap:
|
||||
zeroMem(cast[pointer](addr s.p.data[newLen+1]), newCap - newLen)
|
||||
|
||||
proc nimAddCharV1(s: var NimStringV2; c: char) {.compilerRtl, inl.} =
|
||||
#if (s.p == nil) or (s.len+1 > s.p.cap and not strlitFlag):
|
||||
prepareAdd(s, 1)
|
||||
s.p.data[s.len] = c
|
||||
s.p.data[s.len+1] = '\0'
|
||||
inc s.len
|
||||
s.p.data[s.len] = '\0'
|
||||
|
||||
proc toNimStr(str: cstring, len: int): NimStringV2 {.compilerproc.} =
|
||||
if len <= 0:
|
||||
result = NimStringV2(len: 0, p: nil)
|
||||
else:
|
||||
when compileOption("threads"):
|
||||
var p = cast[ptr NimStrPayload](allocShared0(contentSize(len)))
|
||||
else:
|
||||
var p = cast[ptr NimStrPayload](alloc0(contentSize(len)))
|
||||
var p = allocPayload(len)
|
||||
p.cap = len
|
||||
if len > 0:
|
||||
# we are about to append, so there is no need to copy the \0 terminator:
|
||||
copyMem(unsafeAddr p.data[0], str, len)
|
||||
copyMem(unsafeAddr p.data[0], str, len+1)
|
||||
result = NimStringV2(len: len, p: p)
|
||||
|
||||
proc cstrToNimstr(str: cstring): NimStringV2 {.compilerRtl.} =
|
||||
@@ -99,29 +118,24 @@ proc appendString(dest: var NimStringV2; src: NimStringV2) {.compilerproc, inlin
|
||||
|
||||
proc appendChar(dest: var NimStringV2; c: char) {.compilerproc, inline.} =
|
||||
dest.p.data[dest.len] = c
|
||||
dest.p.data[dest.len+1] = '\0'
|
||||
inc dest.len
|
||||
dest.p.data[dest.len] = '\0'
|
||||
|
||||
proc rawNewString(space: int): NimStringV2 {.compilerproc.} =
|
||||
# this is also 'system.newStringOfCap'.
|
||||
if space <= 0:
|
||||
result = NimStringV2(len: 0, p: nil)
|
||||
else:
|
||||
when compileOption("threads"):
|
||||
var p = cast[ptr NimStrPayload](allocShared0(contentSize(space)))
|
||||
else:
|
||||
var p = cast[ptr NimStrPayload](alloc0(contentSize(space)))
|
||||
var p = allocPayload(space)
|
||||
p.cap = space
|
||||
p.data[0] = '\0'
|
||||
result = NimStringV2(len: 0, p: p)
|
||||
|
||||
proc mnewString(len: int): NimStringV2 {.compilerproc.} =
|
||||
if len <= 0:
|
||||
result = NimStringV2(len: 0, p: nil)
|
||||
else:
|
||||
when compileOption("threads"):
|
||||
var p = cast[ptr NimStrPayload](allocShared0(contentSize(len)))
|
||||
else:
|
||||
var p = cast[ptr NimStrPayload](alloc0(contentSize(len)))
|
||||
var p = allocPayload0(len)
|
||||
p.cap = len
|
||||
result = NimStringV2(len: len, p: p)
|
||||
|
||||
@@ -129,8 +143,25 @@ proc setLengthStrV2(s: var NimStringV2, newLen: int) {.compilerRtl.} =
|
||||
if newLen == 0:
|
||||
discard "do not free the buffer here, pattern 's.setLen 0' is common for avoiding allocations"
|
||||
else:
|
||||
if newLen > s.len or isLiteral(s):
|
||||
prepareAdd(s, newLen - s.len)
|
||||
if isLiteral(s):
|
||||
let oldP = s.p
|
||||
s.p = allocPayload(newLen)
|
||||
s.p.cap = newLen
|
||||
if s.len > 0:
|
||||
copyMem(unsafeAddr s.p.data[0], unsafeAddr oldP.data[0], min(s.len, newLen))
|
||||
if newLen > s.len:
|
||||
zeroMem(cast[pointer](addr s.p.data[s.len]), newLen - s.len + 1)
|
||||
else:
|
||||
s.p.data[newLen] = '\0'
|
||||
else:
|
||||
zeroMem(cast[pointer](addr s.p.data[0]), newLen + 1)
|
||||
elif newLen > s.len:
|
||||
let oldCap = s.p.cap and not strlitFlag
|
||||
if newLen > oldCap:
|
||||
let newCap = max(newLen, resize(oldCap))
|
||||
s.p = reallocPayload0(s.p, oldCap, newCap)
|
||||
s.p.cap = newCap
|
||||
|
||||
s.p.data[newLen] = '\0'
|
||||
s.len = newLen
|
||||
|
||||
@@ -147,10 +178,7 @@ proc nimAsgnStrV2(a: var NimStringV2, b: NimStringV2) {.compilerRtl.} =
|
||||
# 'let y = newStringOfCap(); var x = y'
|
||||
# on the other hand... These get turned into moves now.
|
||||
frees(a)
|
||||
when compileOption("threads"):
|
||||
a.p = cast[ptr NimStrPayload](allocShared0(contentSize(b.len)))
|
||||
else:
|
||||
a.p = cast[ptr NimStrPayload](alloc0(contentSize(b.len)))
|
||||
a.p = allocPayload(b.len)
|
||||
a.p.cap = b.len
|
||||
a.len = b.len
|
||||
copyMem(unsafeAddr a.p.data[0], unsafeAddr b.p.data[0], b.len+1)
|
||||
@@ -158,10 +186,7 @@ proc nimAsgnStrV2(a: var NimStringV2, b: NimStringV2) {.compilerRtl.} =
|
||||
proc nimPrepareStrMutationImpl(s: var NimStringV2) =
|
||||
let oldP = s.p
|
||||
# can't mutate a literal, so we need a fresh copy here:
|
||||
when compileOption("threads"):
|
||||
s.p = cast[ptr NimStrPayload](allocShared0(contentSize(s.len)))
|
||||
else:
|
||||
s.p = cast[ptr NimStrPayload](alloc0(contentSize(s.len)))
|
||||
s.p = allocPayload(s.len)
|
||||
s.p.cap = s.len
|
||||
copyMem(unsafeAddr s.p.data[0], unsafeAddr oldP.data[0], s.len+1)
|
||||
|
||||
@@ -177,9 +202,6 @@ proc prepareMutation*(s: var string) {.inline.} =
|
||||
nimPrepareStrMutationV2(cast[ptr NimStringV2](s)[])
|
||||
|
||||
|
||||
template capacityImpl(str: NimStringV2): int =
|
||||
if str.p != nil: str.p.cap else: 0
|
||||
|
||||
func capacity*(self: string): int {.inline.} =
|
||||
## Returns the current capacity of the string.
|
||||
# See https://github.com/nim-lang/RFCs/issues/460
|
||||
@@ -188,6 +210,5 @@ func capacity*(self: string): int {.inline.} =
|
||||
str.add "Nim"
|
||||
assert str.capacity == 42
|
||||
|
||||
{.cast(noSideEffect).}:
|
||||
let str = unsafeAddr self
|
||||
result = capacityImpl(cast[ptr NimStringV2](str)[])
|
||||
let str = cast[ptr NimStringV2](unsafeAddr self)
|
||||
result = if str.p != nil: str.p.cap and not strlitFlag else: 0
|
||||
|
||||
@@ -340,3 +340,25 @@ proc setLengthSeqV2(s: PGenericSeq, typ: PNimType, newLen: int): PGenericSeq {.
|
||||
result = s
|
||||
zeroMem(dataPointer(result, elemAlign, elemSize, result.len), (newLen-%result.len) *% elemSize)
|
||||
result.len = newLen
|
||||
|
||||
func capacity*(self: string): int {.inline.} =
|
||||
## Returns the current capacity of the string.
|
||||
# See https://github.com/nim-lang/RFCs/issues/460
|
||||
runnableExamples:
|
||||
var str = newStringOfCap(cap = 42)
|
||||
str.add "Nim"
|
||||
assert str.capacity == 42
|
||||
|
||||
let str = cast[NimString](self)
|
||||
result = if str != nil: str.space else: 0
|
||||
|
||||
func capacity*[T](self: seq[T]): int {.inline.} =
|
||||
## Returns the current capacity of the seq.
|
||||
# See https://github.com/nim-lang/RFCs/issues/460
|
||||
runnableExamples:
|
||||
var lst = newSeqOfCap[string](cap = 42)
|
||||
lst.add "Nim"
|
||||
assert lst.capacity == 42
|
||||
|
||||
let sek = cast[PGenericSeq](self)
|
||||
result = if sek != nil: sek.space else: 0
|
||||
|
||||
@@ -24,11 +24,13 @@ proc testRst2Html(fixup = false) =
|
||||
let sourceFile = expectedHtml.replace('\\', '/').replace("/expected/", "/source/").replace(".html", ".rst")
|
||||
exec("$1 rst2html $2" % [nimExe, sourceFile])
|
||||
let producedHtml = expectedHtml.replace('\\', '/').replace("/expected/", "/source/htmldocs/")
|
||||
if readFile(expectedHtml) != readFile(producedHtml):
|
||||
let versionCacheParam = "?v=" & $NimMajor & "." & $NimMinor & "." & $NimPatch
|
||||
let producedFile = readFile(producedHtml).replace(versionCacheParam,"") #remove version cache param used for cache invalidation
|
||||
if readFile(expectedHtml) != producedFile:
|
||||
echo diffFiles(expectedHtml, producedHtml).output
|
||||
inc failures
|
||||
if fixup:
|
||||
copyFile(producedHtml, expectedHtml)
|
||||
writeFile(expectedHtml, producedFile)
|
||||
else:
|
||||
echo "SUCCESS: files identical: ", producedHtml
|
||||
if failures == 0:
|
||||
|
||||
@@ -59,16 +59,18 @@ proc testNimDoc(prjDir, docsDir: string; switches: NimSwitches; fixup = false) =
|
||||
echo("$1 buildIndex $2" % [nimExe, nimBuildIndexSwitches])
|
||||
|
||||
for expected in walkDirRec(prjDir / "expected/", checkDir=true):
|
||||
let versionCacheParam = "?v=" & $NimMajor & "." & $NimMinor & "." & $NimPatch
|
||||
let produced = expected.replace('\\', '/').replace("/expected/", "/$1/" % [docsDir])
|
||||
if not fileExists(produced):
|
||||
echo "FAILURE: files not found: ", produced
|
||||
inc failures
|
||||
elif readFile(expected) != readFile(produced):
|
||||
let producedFile = readFile(produced).replace(versionCacheParam,"") #remove version cache param used for cache invalidation
|
||||
if readFile(expected) != producedFile:
|
||||
echo "FAILURE: files differ: ", produced
|
||||
echo diffFiles(expected, produced).output
|
||||
inc failures
|
||||
if fixup:
|
||||
copyFile(produced, expected)
|
||||
writeFile(expected, producedFile)
|
||||
else:
|
||||
echo "SUCCESS: files identical: ", produced
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import strformat
|
||||
import algorithm
|
||||
import tables
|
||||
import times
|
||||
import procmonitor
|
||||
|
||||
template tryImport(module) = import module
|
||||
|
||||
@@ -43,6 +44,7 @@ when defined(windows):
|
||||
else:
|
||||
import posix
|
||||
|
||||
const HighestSuggestProtocolVersion = 4
|
||||
const DummyEof = "!EOF!"
|
||||
const Usage = """
|
||||
Nimsuggest - Tool to give every editor IDE like capabilities for Nim
|
||||
@@ -55,12 +57,18 @@ Options:
|
||||
--address:HOST binds to that address, by default ""
|
||||
--stdin read commands from stdin and write results to
|
||||
stdout instead of using sockets
|
||||
--clientProcessId:PID shutdown nimsuggest in case this process dies
|
||||
--epc use emacs epc mode
|
||||
--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
|
||||
--v4 use version 4 of the protocol
|
||||
--info:X information
|
||||
--info:nimVer return the Nim compiler version that nimsuggest uses internally
|
||||
--info:protocolVer return the newest protocol version that is supported
|
||||
--info:capabilities return the capabilities supported by nimsuggest
|
||||
--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
|
||||
@@ -117,6 +125,10 @@ const
|
||||
"type 'quit' to quit\n" &
|
||||
"type 'debug' to toggle debug mode on/off\n" &
|
||||
"type 'terse' to toggle terse mode on/off"
|
||||
#List of currently supported capabilities. So lang servers/ides can iterate over and check for what's enabled
|
||||
Capabilities = [
|
||||
"con" #current NimSuggest supports the `con` commmand
|
||||
]
|
||||
|
||||
proc parseQuoted(cmd: string; outp: var string; start: int): int =
|
||||
var i = start
|
||||
@@ -161,7 +173,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", "globalSymbols", "recompile", "saved", "chkFile", "declaration"]:
|
||||
for command in ["sug", "con", "def", "use", "dus", "chk", "mod", "globalSymbols", "recompile", "saved", "chkFile", "declaration", "inlayHints"]:
|
||||
let
|
||||
cmd = sexp(command)
|
||||
methodDesc = newSList()
|
||||
@@ -197,7 +209,7 @@ proc executeNoHooks(cmd: IdeCmd, file, dirtyfile: AbsoluteFile, line, col: int,
|
||||
graph: ModuleGraph) =
|
||||
let conf = graph.config
|
||||
|
||||
if conf.suggestVersion == 3:
|
||||
if conf.suggestVersion >= 3:
|
||||
let command = fmt "cmd = {cmd} {file}:{line}:{col}"
|
||||
benchmark command:
|
||||
executeNoHooksV3(cmd, file, dirtyfile, line, col, tag, graph)
|
||||
@@ -486,6 +498,11 @@ proc execCmd(cmd: string; graph: ModuleGraph; cachedMsgs: CachedMsgs) =
|
||||
of "chkfile": conf.ideCmd = ideChkFile
|
||||
of "recompile": conf.ideCmd = ideRecompile
|
||||
of "type": conf.ideCmd = ideType
|
||||
of "inlayhints":
|
||||
if conf.suggestVersion >= 4:
|
||||
conf.ideCmd = ideInlayHints
|
||||
else:
|
||||
err()
|
||||
else: err()
|
||||
var dirtyfile = ""
|
||||
var orig = ""
|
||||
@@ -550,7 +567,7 @@ proc mainThread(graph: ModuleGraph) =
|
||||
else:
|
||||
os.sleep 250
|
||||
idle += 1
|
||||
if idle == 20 and gRefresh and conf.suggestVersion != 3:
|
||||
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
|
||||
@@ -581,7 +598,7 @@ proc mainCommand(graph: ModuleGraph) =
|
||||
# do not print errors, but log them
|
||||
conf.writelnHook = proc (msg: string) = discard
|
||||
|
||||
if graph.config.suggestVersion == 3:
|
||||
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)
|
||||
@@ -595,6 +612,9 @@ proc mainCommand(graph: ModuleGraph) =
|
||||
open(requests)
|
||||
open(results)
|
||||
|
||||
if graph.config.clientProcessId != 0:
|
||||
hookProcMonitor(graph.config.clientProcessId)
|
||||
|
||||
case gMode
|
||||
of mstdin: createThread(inputThread, replStdin, (gPort, gAddress))
|
||||
of mtcp: createThread(inputThread, replTcp, (gPort, gAddress))
|
||||
@@ -645,6 +665,20 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string; conf: ConfigRef) =
|
||||
of "v1": conf.suggestVersion = 1
|
||||
of "v2": conf.suggestVersion = 0
|
||||
of "v3": conf.suggestVersion = 3
|
||||
of "v4": conf.suggestVersion = 4
|
||||
of "info":
|
||||
case p.val.normalize
|
||||
of "protocolver":
|
||||
stdout.writeLine(HighestSuggestProtocolVersion)
|
||||
quit 0
|
||||
of "nimver":
|
||||
stdout.writeLine(system.NimVersion)
|
||||
quit 0
|
||||
of "capabilities":
|
||||
stdout.writeLine(Capabilities.toSeq.mapIt($it).join(" "))
|
||||
quit 0
|
||||
else:
|
||||
processSwitch(pass, p, conf)
|
||||
of "tester":
|
||||
gMode = mstdin
|
||||
gEmitEof = true
|
||||
@@ -659,6 +693,8 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string; conf: ConfigRef) =
|
||||
conf.suggestMaxResults = parseInt(p.val)
|
||||
of "find":
|
||||
findProject = true
|
||||
of "clientprocessid":
|
||||
conf.clientProcessId = parseInt(p.val)
|
||||
else: processSwitch(pass, p, conf)
|
||||
of cmdArgument:
|
||||
let a = unixToNativePath(p.key)
|
||||
@@ -756,6 +792,18 @@ proc findSymData(graph: ModuleGraph, trackPos: TLineInfo):
|
||||
result[] = s
|
||||
break
|
||||
|
||||
func isInRange*(current, startPos, endPos: TLineInfo, tokenLen: int): bool =
|
||||
result = current.fileIndex == startPos.fileIndex and
|
||||
(current.line > startPos.line or (current.line == startPos.line and current.col>=startPos.col)) and
|
||||
(current.line < endPos.line or (current.line == endPos.line and current.col <= endPos.col))
|
||||
|
||||
proc findSymDataInRange(graph: ModuleGraph, startPos, endPos: TLineInfo):
|
||||
seq[SymInfoPair] =
|
||||
result = newSeq[SymInfoPair]()
|
||||
for s in graph.fileSymbols(startPos.fileIndex).deduplicateSymInfoPair:
|
||||
if isInRange(s.info, startPos, endPos, s.sym.name.s.len):
|
||||
result.add(s)
|
||||
|
||||
proc findSymData(graph: ModuleGraph, file: AbsoluteFile; line, col: int):
|
||||
ref SymInfoPair =
|
||||
let
|
||||
@@ -763,6 +811,14 @@ proc findSymData(graph: ModuleGraph, file: AbsoluteFile; line, col: int):
|
||||
trackPos = newLineInfo(fileIdx, line, col)
|
||||
result = findSymData(graph, trackPos)
|
||||
|
||||
proc findSymDataInRange(graph: ModuleGraph, file: AbsoluteFile; startLine, startCol, endLine, endCol: int):
|
||||
seq[SymInfoPair] =
|
||||
let
|
||||
fileIdx = fileInfoIdx(graph.config, file)
|
||||
startPos = newLineInfo(fileIdx, startLine, startCol)
|
||||
endPos = newLineInfo(fileIdx, endLine, endCol)
|
||||
result = findSymDataInRange(graph, startPos, endPos)
|
||||
|
||||
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:
|
||||
@@ -785,6 +841,23 @@ proc suggestResult(graph: ModuleGraph, sym: PSym, info: TLineInfo,
|
||||
endLine = endLine, endCol = endCol)
|
||||
suggestResult(graph.config, suggest)
|
||||
|
||||
proc suggestInlayHintResult(graph: ModuleGraph, sym: PSym, info: TLineInfo,
|
||||
defaultSection = ideNone, endLine: uint16 = 0, endCol = 0) =
|
||||
let section = if defaultSection != ideNone:
|
||||
defaultSection
|
||||
elif sym.info.exactEquals(info):
|
||||
ideDef
|
||||
else:
|
||||
ideUse
|
||||
var suggestDef = symToSuggest(graph, sym, isLocal=false, section,
|
||||
info, 100, PrefixMatch.None, false, 0, true,
|
||||
endLine = endLine, endCol = endCol)
|
||||
suggestDef.inlayHintInfo = suggestToSuggestInlayHint(suggestDef)
|
||||
suggestDef.section = ideInlayHints
|
||||
if sym.kind == skForVar:
|
||||
suggestDef.inlayHintInfo.allowInsert = false
|
||||
suggestResult(graph.config, suggestDef)
|
||||
|
||||
const
|
||||
# kinds for ideOutline and ideGlobalSymbols
|
||||
searchableSymKinds = {skField, skEnumField, skIterator, skMethod, skFunc, skProc, skConverter, skTemplate}
|
||||
@@ -892,7 +965,7 @@ proc executeNoHooksV3(cmd: IdeCmd, file: AbsoluteFile, dirtyfile: AbsoluteFile,
|
||||
graph.markDirtyIfNeeded(dirtyFile.string, fileInfoIdx(conf, file))
|
||||
|
||||
# these commands require fully compiled project
|
||||
if cmd in {ideUse, ideDus, ideGlobalSymbols, ideChk} and graph.needsCompilation():
|
||||
if cmd in {ideUse, ideDus, ideGlobalSymbols, ideChk, ideInlayHints} 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
|
||||
@@ -901,10 +974,10 @@ proc executeNoHooksV3(cmd: IdeCmd, file: AbsoluteFile, dirtyfile: AbsoluteFile,
|
||||
graph.unmarkAllDirty()
|
||||
|
||||
# these commands require partially compiled project
|
||||
elif cmd in {ideSug, ideOutline, ideHighlight, ideDef, ideChkFile, ideType, ideDeclaration, ideExpand} and
|
||||
(graph.needsCompilation(fileIndex) or cmd == ideSug):
|
||||
elif cmd in {ideSug, ideCon, ideOutline, ideHighlight, ideDef, ideChkFile, ideType, ideDeclaration, ideExpand} and
|
||||
(graph.needsCompilation(fileIndex) or cmd in {ideSug, ideCon}):
|
||||
# for ideSug use v2 implementation
|
||||
if cmd == ideSug:
|
||||
if cmd in {ideSug, ideCon}:
|
||||
conf.m.trackPos = newLineInfo(fileIndex, line, col)
|
||||
conf.m.trackPosAttached = false
|
||||
else:
|
||||
@@ -950,6 +1023,9 @@ proc executeNoHooksV3(cmd: IdeCmd, file: AbsoluteFile, dirtyfile: AbsoluteFile,
|
||||
# ideSug performs partial build of the file, thus mark it dirty for the
|
||||
# future calls.
|
||||
graph.markDirtyIfNeeded(file.string, fileIndex)
|
||||
of ideCon:
|
||||
graph.markDirty fileIndex
|
||||
graph.markClientsDirty fileIndex
|
||||
of ideOutline:
|
||||
let n = parseFile(fileIndex, graph.cache, graph.config)
|
||||
graph.iterateOutlineNodes(n, graph.fileSymbols(fileIndex).deduplicateSymInfoPair)
|
||||
@@ -1048,6 +1124,19 @@ proc executeNoHooksV3(cmd: IdeCmd, file: AbsoluteFile, dirtyfile: AbsoluteFile,
|
||||
|
||||
graph.markDirty fileIndex
|
||||
graph.markClientsDirty fileIndex
|
||||
of ideInlayHints:
|
||||
myLog fmt "Executing inlayHints"
|
||||
var endLine = 0
|
||||
var endCol = -1
|
||||
var i = 0
|
||||
i += skipWhile(tag, seps, i)
|
||||
i += parseInt(tag, endLine, i)
|
||||
i += skipWhile(tag, seps, i)
|
||||
i += parseInt(tag, endCol, i)
|
||||
let s = graph.findSymDataInRange(file, line, col, endLine, endCol)
|
||||
for q in s:
|
||||
if q.sym.kind in {skLet, skVar, skForVar, skConst} and q.isDecl and not q.sym.hasUserSpecifiedType:
|
||||
graph.suggestInlayHintResult(q.sym, q.info, ideInlayHints)
|
||||
else:
|
||||
myLog fmt "Discarding {cmd}"
|
||||
|
||||
|
||||
34
nimsuggest/procmonitor.nim
Normal file
34
nimsuggest/procmonitor.nim
Normal file
@@ -0,0 +1,34 @@
|
||||
# Monitor a client process and shutdown the current process, if the client
|
||||
# process is found to be dead
|
||||
|
||||
import os
|
||||
|
||||
when defined(posix):
|
||||
import posix_utils
|
||||
import posix
|
||||
|
||||
when defined(windows):
|
||||
import winlean
|
||||
|
||||
when defined(posix):
|
||||
proc monitorClientProcessIdThreadProc(pid: int) {.thread.} =
|
||||
while true:
|
||||
sleep(1000)
|
||||
try:
|
||||
sendSignal(Pid(pid), 0)
|
||||
except:
|
||||
discard kill(Pid(getCurrentProcessId()), cint(SIGTERM))
|
||||
|
||||
when defined(windows):
|
||||
proc monitorClientProcessIdThreadProc(pid: int) {.thread.} =
|
||||
var process = openProcess(SYNCHRONIZE, 0, DWORD(pid))
|
||||
if process != 0:
|
||||
discard waitForSingleObject(process, INFINITE)
|
||||
discard closeHandle(process)
|
||||
quit(0)
|
||||
|
||||
var tid: Thread[int]
|
||||
|
||||
proc hookProcMonitor*(pid: int) =
|
||||
when defined(posix) or defined(windows):
|
||||
createThread(tid, monitorClientProcessIdThreadProc, pid)
|
||||
12
nimsuggest/tests/tconcept1.nim
Normal file
12
nimsuggest/tests/tconcept1.nim
Normal file
@@ -0,0 +1,12 @@
|
||||
SomeNumber = concept
|
||||
|
||||
#[!]#
|
||||
discard """
|
||||
$nimsuggest --tester $file
|
||||
>chk $1
|
||||
chk;;skUnknown;;;;Hint;;???;;0;;-1;;">> (toplevel): import(dirty): tests/tconcept1.nim [Processing]";;0
|
||||
chk;;skUnknown;;;;Error;;$file;;1;;13;;"the \'concept\' keyword is only valid in \'type\' sections";;0
|
||||
chk;;skUnknown;;;;Error;;$file;;1;;13;;"invalid indentation";;0
|
||||
chk;;skUnknown;;;;Error;;$file;;1;;13;;"expression expected, but found \'keyword concept\'";;0
|
||||
chk;;skUnknown;;;;Error;;$file;;1;;0;;"\'SomeNumber\' cannot be assigned to";;0
|
||||
"""
|
||||
15
nimsuggest/tests/tconcept2.nim
Normal file
15
nimsuggest/tests/tconcept2.nim
Normal file
@@ -0,0 +1,15 @@
|
||||
SomeNumber = concept a, type T
|
||||
a.int is int
|
||||
int.to(T) is type(a)
|
||||
|
||||
#[!]#
|
||||
discard """
|
||||
$nimsuggest --tester $file
|
||||
>chk $1
|
||||
chk;;skUnknown;;;;Hint;;???;;0;;-1;;">> (toplevel): import(dirty): tests/tconcept2.nim [Processing]";;0
|
||||
chk;;skUnknown;;;;Error;;$file;;1;;2;;"invalid indentation";;0
|
||||
chk;;skUnknown;;;;Error;;$file;;1;;15;;"the \'concept\' keyword is only valid in \'type\' sections";;0
|
||||
chk;;skUnknown;;;;Error;;$file;;1;;15;;"invalid indentation";;0
|
||||
chk;;skUnknown;;;;Error;;$file;;1;;15;;"expression expected, but found \'keyword concept\'";;0
|
||||
chk;;skUnknown;;;;Error;;$file;;1;;2;;"\'SomeNumber\' cannot be assigned to";;0
|
||||
"""
|
||||
@@ -1,9 +1,9 @@
|
||||
discard """
|
||||
$nimsuggest --tester $file
|
||||
>def $1
|
||||
def;;skProc;;tdef1.hello;;proc (): string{.noSideEffect, gcsafe.};;$file;;9;;5;;"Return hello";;100
|
||||
def;;skProc;;tdef1.hello;;proc (): string{.noSideEffect, gcsafe, raises: <inferred> [].};;$file;;9;;5;;"Return hello";;100
|
||||
>def $1
|
||||
def;;skProc;;tdef1.hello;;proc (): string{.noSideEffect, gcsafe.};;$file;;9;;5;;"Return hello";;100
|
||||
def;;skProc;;tdef1.hello;;proc (): string{.noSideEffect, gcsafe, raises: <inferred> [].};;$file;;9;;5;;"Return hello";;100
|
||||
"""
|
||||
|
||||
proc hello(): string =
|
||||
|
||||
@@ -15,7 +15,7 @@ discard """
|
||||
$nimsuggest --tester --maxresults:2 $file
|
||||
>sug $1
|
||||
sug;;skProc;;tdot4.main;;proc (inp: string): string;;$file;;6;;5;;"";;100;;None
|
||||
sug;;skFunc;;mstrutils.replace;;proc (s: string, sub: string, by: string): string{.noSideEffect, gcsafe.};;*fixtures/mstrutils.nim;;9;;5;;"this is a test version of strutils.replace, it simply returns `by`";;100;;None
|
||||
sug;;skFunc;;mstrutils.replace;;proc (s: string, sub: string, by: string): string{.noSideEffect, gcsafe, raises: <inferred> [].};;*fixtures/mstrutils.nim;;9;;5;;"this is a test version of strutils.replace, it simply returns `by`";;100;;None
|
||||
"""
|
||||
|
||||
# TODO - determine appropriate behaviour for further suggest output and test it
|
||||
|
||||
15
nimsuggest/tests/tfatal1.nim
Normal file
15
nimsuggest/tests/tfatal1.nim
Normal file
@@ -0,0 +1,15 @@
|
||||
{.warning: "I'm a warning!".}
|
||||
{.error: "I'm an error!".}
|
||||
{.fatal: "I'm a fatal error!".}
|
||||
{.error: "I'm an error after fatal error!".}
|
||||
|
||||
#[!]#
|
||||
discard """
|
||||
$nimsuggest --tester $file
|
||||
>chk $1
|
||||
chk;;skUnknown;;;;Hint;;???;;0;;-1;;">> (toplevel): import(dirty): tests/tfatal1.nim [Processing]";;0
|
||||
chk;;skUnknown;;;;Warning;;$file;;1;;9;;"I\'m a warning! [User]";;0
|
||||
chk;;skUnknown;;;;Error;;$file;;2;;7;;"I\'m an error!";;0
|
||||
chk;;skUnknown;;;;Error;;$file;;3;;7;;"fatal error: I\'m a fatal error!";;0
|
||||
chk;;skUnknown;;;;Error;;$file;;4;;7;;"I\'m an error after fatal error!";;0
|
||||
"""
|
||||
@@ -11,7 +11,7 @@ go()
|
||||
discard """
|
||||
$nimsuggest --tester $file
|
||||
>def $path/tinclude.nim:7:14
|
||||
def;;skProc;;minclude_import.create;;proc (greeting: string, subject: string): Greet{.noSideEffect, gcsafe.};;*fixtures/minclude_include.nim;;3;;5;;"";;100
|
||||
def;;skProc;;minclude_import.create;;proc (greeting: string, subject: string): Greet{.noSideEffect, gcsafe, raises: <inferred> [].};;*fixtures/minclude_include.nim;;3;;5;;"";;100
|
||||
>def $path/fixtures/minclude_include.nim:3:71
|
||||
def;;skType;;minclude_types.Greet;;Greet;;*fixtures/minclude_types.nim;;4;;2;;"";;100
|
||||
>def $path/fixtures/minclude_include.nim:3:71
|
||||
|
||||
@@ -6,7 +6,7 @@ tmp#[!]#
|
||||
discard """
|
||||
$nimsuggest --tester $file
|
||||
>sug $1
|
||||
sug;;skMacro;;tsug_template.tmpb;;macro (){.noSideEffect, gcsafe.};;$file;;2;;6;;"";;100;;Prefix
|
||||
sug;;skMacro;;tsug_template.tmpb;;macro (){.noSideEffect, gcsafe, raises: <inferred> [].};;$file;;2;;6;;"";;100;;Prefix
|
||||
sug;;skConverter;;tsug_template.tmpc;;converter ();;$file;;3;;10;;"";;100;;Prefix
|
||||
sug;;skTemplate;;tsug_template.tmpa;;template ();;$file;;1;;9;;"";;100;;Prefix
|
||||
"""
|
||||
|
||||
@@ -14,9 +14,9 @@ proc #[!]#someProc*() =
|
||||
discard """
|
||||
$nimsuggest --tester $file
|
||||
>use $1
|
||||
def;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe.};;$file;;9;;5;;"";;100
|
||||
use;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe.};;$file;;12;;0;;"";;100
|
||||
def;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe, raises: <inferred> [].};;$file;;9;;5;;"";;100
|
||||
use;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe, raises: <inferred> [].};;$file;;12;;0;;"";;100
|
||||
>use $2
|
||||
def;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe.};;$file;;9;;5;;"";;100
|
||||
use;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe.};;$file;;12;;0;;"";;100
|
||||
def;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe, raises: <inferred> [].};;$file;;9;;5;;"";;100
|
||||
use;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe, raises: <inferred> [].};;$file;;12;;0;;"";;100
|
||||
"""
|
||||
|
||||
15
nimsuggest/tests/tuse_enum.nim
Normal file
15
nimsuggest/tests/tuse_enum.nim
Normal file
@@ -0,0 +1,15 @@
|
||||
discard """
|
||||
$nimsuggest --tester $file
|
||||
>use $1
|
||||
def;;skEnumField;;tuse_enum.Colour.Red;;Colour;;$file;;10;;4;;"";;100
|
||||
use;;skEnumField;;tuse_enum.Colour.Red;;Colour;;$file;;14;;8;;"";;100
|
||||
"""
|
||||
|
||||
type
|
||||
Colour = enum
|
||||
Red
|
||||
Green
|
||||
Blue
|
||||
|
||||
discard #[!]#Red
|
||||
|
||||
@@ -19,7 +19,7 @@ def skField tv3.Foo.bar string $file 5 4 "" 100
|
||||
>sug $1
|
||||
sug skField bar string $file 5 4 "" 100 Prefix
|
||||
>globalSymbols test
|
||||
def skProc tv3.test proc (f: Foo){.gcsafe.} $file 7 5 "" 100
|
||||
def skProc tv3.test proc (f: Foo){.gcsafe, raises: <inferred> [].} $file 7 5 "" 100
|
||||
>globalSymbols Foo
|
||||
def skType tv3.Foo Foo $file 4 2 "" 100
|
||||
>def $2
|
||||
|
||||
13
nimsuggest/tests/tv3_con.nim
Normal file
13
nimsuggest/tests/tv3_con.nim
Normal file
@@ -0,0 +1,13 @@
|
||||
# tests v3
|
||||
|
||||
proc test(a: string, b:string) = discard
|
||||
proc test(a: int) = discard
|
||||
|
||||
test(#[!]#
|
||||
|
||||
discard """
|
||||
$nimsuggest --v3 --tester $file
|
||||
>con $1
|
||||
con;;skProc;;tv3_con.test;;proc (a: string, b: string);;$file;;3;;5;;"";;100
|
||||
con;;skProc;;tv3_con.test;;proc (a: int);;$file;;4;;5;;"";;100
|
||||
"""
|
||||
@@ -7,17 +7,17 @@ let a = de#[!]#mo()
|
||||
discard """
|
||||
$nimsuggest --v3 --tester $file
|
||||
>use $1
|
||||
use skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 1 5 "" 100
|
||||
def skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 3 5 "" 100
|
||||
use skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 5 8 "" 100
|
||||
use skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].} $file 1 5 "" 100
|
||||
def skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].} $file 3 5 "" 100
|
||||
use skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].} $file 5 8 "" 100
|
||||
>use $2
|
||||
use skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 1 5 "" 100
|
||||
def skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 3 5 "" 100
|
||||
use skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 5 8 "" 100
|
||||
use skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].} $file 1 5 "" 100
|
||||
def skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].} $file 3 5 "" 100
|
||||
use skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].} $file 5 8 "" 100
|
||||
>declaration $1
|
||||
declaration skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 3 5 "" 100
|
||||
declaration skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].} $file 3 5 "" 100
|
||||
>declaration $2
|
||||
declaration skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 1 5 "" 100
|
||||
declaration skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].} $file 1 5 "" 100
|
||||
>declaration $3
|
||||
declaration skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 1 5 "" 100
|
||||
declaration skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].} $file 1 5 "" 100
|
||||
"""
|
||||
|
||||
@@ -7,8 +7,8 @@ proc BBtokenA(): int = 5
|
||||
discard """
|
||||
$nimsuggest --v3 --tester $file
|
||||
>globalSymbols token
|
||||
def skProc tv3_globalSymbols.token proc (): int{.noSideEffect, gcsafe.} $file 4 5 "" 100
|
||||
def skProc tv3_globalSymbols.tokenA proc (): int{.noSideEffect, gcsafe.} $file 3 5 "" 100
|
||||
def skProc tv3_globalSymbols.Btoken proc (): int{.noSideEffect, gcsafe.} $file 2 5 "" 100
|
||||
def skProc tv3_globalSymbols.BBtokenA proc (): int{.noSideEffect, gcsafe.} $file 5 5 "" 100
|
||||
def skProc tv3_globalSymbols.token proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].} $file 4 5 "" 100
|
||||
def skProc tv3_globalSymbols.tokenA proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].} $file 3 5 "" 100
|
||||
def skProc tv3_globalSymbols.Btoken proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].} $file 2 5 "" 100
|
||||
def skProc tv3_globalSymbols.BBtokenA proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].} $file 5 5 "" 100
|
||||
"""
|
||||
|
||||
@@ -33,13 +33,13 @@ outline skType tv3_outline.FooEnum FooEnum $file 6 2 "" 100 6 31
|
||||
outline skEnumField tv3_outline.FooEnum.value1 FooEnum $file 6 17 "" 100 6 23
|
||||
outline skEnumField tv3_outline.FooEnum.value2 FooEnum $file 6 25 "" 100 6 31
|
||||
outline skType tv3_outline.FooPrivate FooPrivate $file 7 2 "" 100 8 22
|
||||
outline skMacro tv3_outline.m macro (arg: untyped): untyped{.noSideEffect, gcsafe.} $file 10 6 "" 100 10 40
|
||||
outline skMacro tv3_outline.m macro (arg: untyped): untyped{.noSideEffect, gcsafe, raises: <inferred> [].} $file 10 6 "" 100 10 40
|
||||
outline skTemplate tv3_outline.t template (arg: untyped): untyped $file 11 9 "" 100 11 43
|
||||
outline skProc tv3_outline.p proc (){.noSideEffect, gcsafe.} $file 12 5 "" 100 12 24
|
||||
outline skConverter tv3_outline.c converter (s: string): int{.noSideEffect, gcsafe.} $file 14 10 "" 100 14 37
|
||||
outline skFunc tv3_outline.f proc (){.noSideEffect, gcsafe.} $file 16 5 "" 100 16 24
|
||||
outline skProc tv3_outline.p proc (){.noSideEffect, gcsafe, raises: <inferred> [].} $file 12 5 "" 100 12 24
|
||||
outline skConverter tv3_outline.c converter (s: string): int{.noSideEffect, gcsafe, raises: <inferred> [].} $file 14 10 "" 100 14 37
|
||||
outline skFunc tv3_outline.f proc (){.noSideEffect, gcsafe, raises: <inferred> [].} $file 16 5 "" 100 16 24
|
||||
outline skConst tv3_outline.con int literal(2) $file 20 6 "" 100 20 13
|
||||
outline skProc tv3_outline.outer proc (){.noSideEffect, gcsafe.} $file 22 5 "" 100 23 24
|
||||
outline skProc tv3_outline.outer.inner proc (){.noSideEffect, gcsafe.} $file 23 7 "" 100 23 24
|
||||
outline skProc tv3_outline.procWithLocal proc (){.noSideEffect, gcsafe.} $file 25 5 "" 100 26 16
|
||||
outline skProc tv3_outline.outer proc (){.noSideEffect, gcsafe, raises: <inferred> [].} $file 22 5 "" 100 23 24
|
||||
outline skProc tv3_outline.outer.inner proc (){.noSideEffect, gcsafe, raises: <inferred> [].} $file 23 7 "" 100 23 24
|
||||
outline skProc tv3_outline.procWithLocal proc (){.noSideEffect, gcsafe, raises: <inferred> [].} $file 25 5 "" 100 26 16
|
||||
"""
|
||||
|
||||
@@ -45,7 +45,7 @@ $nimsuggest --tester --maxresults:5 $file
|
||||
>sug $1
|
||||
sug;;skField;;age;;int;;$file;;6;;6;;"";;100;;None
|
||||
sug;;skField;;name;;string;;$file;;5;;6;;"";;100;;None
|
||||
sug;;skMethod;;twithin_macro.age_human_yrs;;proc (self: Animal): int;;$file;;8;;9;;"";;100;;None
|
||||
sug;;skMethod;;twithin_macro.vocalize;;proc (self: Animal): string;;$file;;7;;9;;"";;100;;None
|
||||
sug;;skMethod;;twithin_macro.age_human_yrs;;proc (self: Animal): int{.raises: <inferred> [].};;$file;;8;;9;;"";;100;;None
|
||||
sug;;skMethod;;twithin_macro.vocalize;;proc (self: Animal): string{.raises: <inferred> [].};;$file;;7;;9;;"";;100;;None
|
||||
sug;;skMethod;;twithin_macro.vocalize;;proc (self: Rabbit): string;;$file;;23;;9;;"";;100;;None
|
||||
"""
|
||||
|
||||
@@ -44,5 +44,5 @@ discard """
|
||||
$nimsuggest --tester $file
|
||||
>sug $1
|
||||
sug;;skField;;age;;int;;$file;;6;;6;;"";;100;;Prefix
|
||||
sug;;skMethod;;twithin_macro_prefix.age_human_yrs;;proc (self: Animal): int;;$file;;8;;9;;"";;100;;Prefix
|
||||
sug;;skMethod;;twithin_macro_prefix.age_human_yrs;;proc (self: Animal): int{.raises: <inferred> [].};;$file;;8;;9;;"";;100;;Prefix
|
||||
"""
|
||||
|
||||
@@ -46,7 +46,7 @@ pkg "BipBuffer"
|
||||
pkg "blscurve", allowFailure = true
|
||||
pkg "bncurve"
|
||||
pkg "brainfuck", "nim c -d:release -r tests/compile.nim"
|
||||
pkg "bump", "nim c --gc:arc --path:. -r tests/tbump.nim", "https://github.com/disruptek/bump", allowFailure = true
|
||||
pkg "bump", "nim c --mm:arc --path:. -r tests/tbump.nim", "https://github.com/disruptek/bump", allowFailure = true
|
||||
pkg "c2nim", "nim c testsuite/tester.nim"
|
||||
pkg "cascade"
|
||||
pkg "cello", url = "https://github.com/nim-lang/cello", useHead = true
|
||||
@@ -55,7 +55,7 @@ pkg "chroma"
|
||||
pkg "chronicles", "nim c -o:chr -r chronicles.nim"
|
||||
pkg "chronos", "nim c -r -d:release tests/testall"
|
||||
pkg "cligen", "nim c --path:. -r cligen.nim"
|
||||
pkg "combparser", "nimble test --gc:orc"
|
||||
pkg "combparser", "nimble test --mm:orc"
|
||||
pkg "compactdict"
|
||||
pkg "comprehension", "nimble test", "https://github.com/alehander92/comprehension"
|
||||
pkg "cowstrings"
|
||||
@@ -75,7 +75,7 @@ pkg "glob"
|
||||
pkg "ggplotnim", "nim c -d:noCairo -r tests/tests.nim"
|
||||
pkg "gittyup", "nimble test", "https://github.com/disruptek/gittyup", allowFailure = true
|
||||
pkg "gnuplot", "nim c gnuplot.nim"
|
||||
# pkg "gram", "nim c -r --gc:arc --define:danger tests/test.nim", "https://github.com/disruptek/gram"
|
||||
# pkg "gram", "nim c -r --mm:arc --define:danger tests/test.nim", "https://github.com/disruptek/gram"
|
||||
# pending https://github.com/nim-lang/Nim/issues/16509
|
||||
pkg "hts", "nim c -o:htss src/hts.nim"
|
||||
pkg "httpauth"
|
||||
@@ -91,13 +91,12 @@ pkg "lockfreequeues"
|
||||
pkg "macroutils"
|
||||
pkg "manu"
|
||||
pkg "markdown"
|
||||
pkg "measuremancer", "nimble install -y unchained@#HEAD; nimble -y test"
|
||||
pkg "measuremancer", "nimble testDeps; nimble -y test"
|
||||
# when unchained is version 0.3.7 or higher, use `nimble testDeps;`
|
||||
pkg "memo"
|
||||
pkg "msgpack4nim", "nim c -r tests/test_spec.nim"
|
||||
pkg "nake", "nim c nakefile.nim"
|
||||
pkg "neo", "nim c -d:blas=openblas --mm:refc tests/all.nim", "https://github.com/metagn/neo"
|
||||
# remove custom url when https://github.com/andreaferretti/neo/pull/53 is merged
|
||||
pkg "neo", "nim c -d:blas=openblas --mm:refc tests/all.nim"
|
||||
pkg "nesm", "nimble tests", "https://github.com/nim-lang/NESM", useHead = true
|
||||
pkg "netty"
|
||||
pkg "nico", allowFailure = true
|
||||
@@ -121,7 +120,7 @@ pkg "nimsl"
|
||||
pkg "nimsvg"
|
||||
pkg "nimterop", "nimble minitest", url = "https://github.com/nim-lang/nimterop"
|
||||
pkg "nimwc", "nim c nimwc.nim", allowFailure = true
|
||||
pkg "nimx", "nim c --threads:on test/main.nim", allowFailure = true
|
||||
pkg "nimx", "nim c test/main.nim", allowFailure = true
|
||||
pkg "nitter", "nim c src/nitter.nim", "https://github.com/zedeus/nitter"
|
||||
pkg "norm", "testament r tests/common/tmodel.nim"
|
||||
pkg "npeg", "nimble testarc"
|
||||
@@ -145,13 +144,13 @@ pkg "RollingHash", "nim c -r tests/test_cyclichash.nim"
|
||||
pkg "rosencrantz", "nim c -o:rsncntz -r rosencrantz.nim"
|
||||
pkg "sdl1", "nim c -r src/sdl.nim"
|
||||
pkg "sdl2_nim", "nim c -r sdl2/sdl.nim"
|
||||
pkg "sigv4", "nim c --gc:arc -r sigv4.nim", "https://github.com/disruptek/sigv4"
|
||||
pkg "sigv4", "nim c --mm:arc -r sigv4.nim", "https://github.com/disruptek/sigv4"
|
||||
pkg "sim"
|
||||
pkg "smtp", "nimble compileExample"
|
||||
pkg "snip", "nimble test", "https://github.com/genotrance/snip"
|
||||
pkg "ssostrings"
|
||||
pkg "stew"
|
||||
pkg "stint", "nim r stint.nim"
|
||||
pkg "stint", "nim c stint.nim"
|
||||
pkg "strslice"
|
||||
pkg "strunicode", "nim c -r --mm:refc src/strunicode.nim"
|
||||
pkg "supersnappy"
|
||||
@@ -168,12 +167,13 @@ pkg "timezones"
|
||||
pkg "tiny_sqlite"
|
||||
pkg "unicodedb", "nim c -d:release -r tests/tests.nim"
|
||||
pkg "unicodeplus", "nim c -d:release -r tests/tests.nim"
|
||||
pkg "union", "nim c -r tests/treadme.nim", url = "https://github.com/alaviss/union"
|
||||
pkg "unpack"
|
||||
pkg "weave", "nimble test_gc_arc", useHead = true
|
||||
pkg "websocket", "nim c websocket.nim"
|
||||
pkg "winim", "nim c winim.nim"
|
||||
pkg "with"
|
||||
pkg "ws", allowFailure = true
|
||||
pkg "yaml", "nim c -r test/tserialization.nim"
|
||||
pkg "yaml"
|
||||
pkg "zero_functional", "nim c -r test.nim"
|
||||
pkg "zippy"
|
||||
|
||||
@@ -51,3 +51,19 @@ type Bug[T] = object
|
||||
|
||||
var bug: Bug[int]
|
||||
doAssert sizeof(bug) == 128, "Oops my size is " & $sizeof(bug) # 16
|
||||
|
||||
|
||||
block: # bug #22419
|
||||
type
|
||||
ValidatorPubKey = object
|
||||
blob: array[96, byte]
|
||||
|
||||
proc f(): auto =
|
||||
return iterator() =
|
||||
var pad: int8 = 0
|
||||
var y {.align: 16.}: ValidatorPubKey
|
||||
let value = cast[uint64](addr y)
|
||||
doAssert value mod 16 == 0
|
||||
|
||||
f()()
|
||||
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
discard """
|
||||
cmd: '''nim c --gc:arc $file'''
|
||||
output: '''2
|
||||
2'''
|
||||
cmd: '''nim c --mm:arc $file'''
|
||||
output: '''
|
||||
2
|
||||
2
|
||||
destroyed
|
||||
'''
|
||||
"""
|
||||
|
||||
type
|
||||
ObjWithDestructor = object
|
||||
a: int
|
||||
proc `=destroy`(self: var ObjWithDestructor) =
|
||||
proc `=destroy`(self: ObjWithDestructor) =
|
||||
echo "destroyed"
|
||||
|
||||
proc `=`(self: var ObjWithDestructor, other: ObjWithDestructor) =
|
||||
proc `=copy`(self: var ObjWithDestructor, other: ObjWithDestructor) =
|
||||
echo "copied"
|
||||
|
||||
proc test(a: range[0..1], arg: ObjWithDestructor) =
|
||||
@@ -38,4 +41,4 @@ proc test(a: range[0..1], arg: ObjWithDestructor) =
|
||||
if iteration == 2:
|
||||
break
|
||||
|
||||
test(1, ObjWithDestructor())
|
||||
test(1, ObjWithDestructor())
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
discard """
|
||||
cmd: '''nim c --gc:arc $file'''
|
||||
output: '''2
|
||||
2'''
|
||||
cmd: '''nim c --mm:arc $file'''
|
||||
output: '''
|
||||
2
|
||||
2
|
||||
destroyed
|
||||
'''
|
||||
"""
|
||||
|
||||
type
|
||||
ObjWithDestructor = object
|
||||
a: int
|
||||
proc `=destroy`(self: var ObjWithDestructor) =
|
||||
proc `=destroy`(self: ObjWithDestructor) =
|
||||
echo "destroyed"
|
||||
|
||||
proc `=copy`(self: var ObjWithDestructor, other: ObjWithDestructor) =
|
||||
|
||||
20
tests/ccgbugs/t22462.nim
Normal file
20
tests/ccgbugs/t22462.nim
Normal file
@@ -0,0 +1,20 @@
|
||||
discard """
|
||||
action: "run"
|
||||
output: '''
|
||||
1
|
||||
1
|
||||
1
|
||||
'''
|
||||
matrix: "--mm:refc"
|
||||
targets: "c cpp"
|
||||
"""
|
||||
|
||||
type Object = object
|
||||
someComplexType: seq[int]
|
||||
index: Natural
|
||||
|
||||
func newObject(): Object = result.index.inc
|
||||
|
||||
for i in 1..3:
|
||||
let o = newObject()
|
||||
echo o.index
|
||||
@@ -123,3 +123,13 @@ proc bug19613 =
|
||||
doAssert x.bid.root.data[0] == 42
|
||||
|
||||
bug19613()
|
||||
|
||||
proc foo = # bug #23280
|
||||
let foo = @[1,2,3,4,5,6]
|
||||
doAssert toOpenArray(foo, 0, 5).len == 6
|
||||
doAssert toOpenArray(foo, 0, 5).len mod 6 == 0 # this should output 0
|
||||
doAssert toOpenArray(foo, 0, 5).max mod 6 == 0
|
||||
let L = toOpenArray(foo, 0, 5).len
|
||||
doAssert L mod 6 == 0
|
||||
|
||||
foo()
|
||||
|
||||
192
tests/codegen/titaniummangle.nim
Normal file
192
tests/codegen/titaniummangle.nim
Normal file
@@ -0,0 +1,192 @@
|
||||
discard """
|
||||
targets: "c cpp"
|
||||
matrix: "--debugger:native"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE6stringN14titaniummangle3FooE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE3int7varargsI6stringE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncEN14titaniummangle3BooE'"
|
||||
ccodecheck: "'_ZN8testFunc8testFuncE8typeDescIN14titaniummangle17EnumAnotherSampleEE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE3ptrI14uncheckedArrayI3intEE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE3setIN14titaniummangle10EnumSampleEE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE4procI6string6stringE'"
|
||||
ccodecheck: "'_ZN8testFunc8testFuncE3intN10Comparable10ComparableE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE3int3int'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncEN14titaniummangle10EnumSampleE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncEN14titaniummangle17EnumAnotherSampleE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE3int3int'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncEN14titaniummangle10EnumSampleE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncEN14titaniummangle17EnumAnotherSampleE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE5tupleI3int3intE7cstring'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE5tupleI5float5floatE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE3ptrI3intE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE3ptrIN14titaniummangle3FooEE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE3ptrI3ptrI3intEE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE3refIN14titaniummangle3FooEE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE3varIN14titaniummangle3FooEE5int325int323refIN14titaniummangle3FooEE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE3varI3intE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE9openArrayI6stringE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE5arrayI7range013intE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE9ContainerI3intE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE10Container2I5int325int32E'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE9ContainerI10Container2I5int325int32EE'"
|
||||
"""
|
||||
|
||||
#When debugging this notice that if one check fails, it can be due to any of the above.
|
||||
|
||||
type
|
||||
Comparable = concept x, y
|
||||
(x < y) is bool
|
||||
|
||||
type
|
||||
Foo = object
|
||||
a: int32
|
||||
b: int32
|
||||
|
||||
FooTuple = tuple
|
||||
a: int
|
||||
b: int
|
||||
Container[T] = object
|
||||
data: T
|
||||
Container2[T, T2] = object
|
||||
data: T
|
||||
data2: T2
|
||||
|
||||
Boo = distinct Foo
|
||||
|
||||
Coo = Foo
|
||||
|
||||
Doo = Boo | Foo
|
||||
|
||||
TestProc = proc(a:string): string
|
||||
|
||||
type EnumSample = enum
|
||||
a, b, c
|
||||
|
||||
type EnumAnotherSample = enum
|
||||
a, b, c
|
||||
|
||||
proc testFunc(a: set[EnumSample]) =
|
||||
echo $a
|
||||
|
||||
proc testFunc(a: typedesc) =
|
||||
echo $a
|
||||
|
||||
proc testFunc(a: ptr Foo) =
|
||||
echo repr a
|
||||
|
||||
proc testFunc(s: string, a: Coo) =
|
||||
echo repr a
|
||||
|
||||
proc testFunc(s: int, a: Comparable) =
|
||||
echo repr a
|
||||
|
||||
proc testFunc(a: TestProc) =
|
||||
let b = ""
|
||||
echo repr a("")
|
||||
|
||||
proc testFunc(a: ref Foo) =
|
||||
echo repr a
|
||||
|
||||
proc testFunc(b: Boo) =
|
||||
echo repr b
|
||||
|
||||
proc testFunc(a: ptr UncheckedArray[int]) =
|
||||
echo repr a
|
||||
|
||||
proc testFunc(a: ptr int) =
|
||||
echo repr a
|
||||
|
||||
proc testFunc(a: ptr ptr int) =
|
||||
echo repr a
|
||||
|
||||
proc testFunc(e: FooTuple, str: cstring) =
|
||||
echo e
|
||||
|
||||
proc testFunc(e: (float, float)) =
|
||||
echo e
|
||||
|
||||
proc testFunc(e: EnumSample) =
|
||||
echo e
|
||||
|
||||
proc testFunc(e: var int) =
|
||||
echo e
|
||||
|
||||
proc testFunc(e: var Foo, a, b: int32, refFoo: ref Foo) =
|
||||
echo e
|
||||
|
||||
proc testFunc(xs: Container[int]) =
|
||||
let a = 2
|
||||
echo xs
|
||||
|
||||
proc testFunc(xs: Container2[int32, int32]) =
|
||||
let a = 2
|
||||
echo xs
|
||||
|
||||
proc testFunc(xs: Container[Container2[int32, int32]]) =
|
||||
let a = 2
|
||||
echo xs
|
||||
|
||||
proc testFunc(xs: seq[int]) =
|
||||
let a = 2
|
||||
echo xs
|
||||
|
||||
proc testFunc(xs: openArray[string]) =
|
||||
let a = 2
|
||||
echo xs
|
||||
|
||||
proc testFunc(xs: array[2, int]) =
|
||||
let a = 2
|
||||
echo xs
|
||||
|
||||
proc testFunc(e: EnumAnotherSample) =
|
||||
echo e
|
||||
|
||||
proc testFunc(a, b: int) =
|
||||
echo "hola"
|
||||
discard
|
||||
|
||||
proc testFunc(a: int, xs: varargs[string]) =
|
||||
let a = 10
|
||||
for x in xs:
|
||||
echo x
|
||||
|
||||
proc testFunc() =
|
||||
var a = 2
|
||||
var aPtr = a.addr
|
||||
var foo = Foo()
|
||||
let refFoo : ref Foo = new(Foo)
|
||||
let b = Foo().Boo()
|
||||
let d: Doo = Foo()
|
||||
testFunc("", Coo())
|
||||
testFunc(1, )
|
||||
testFunc(b)
|
||||
testFunc(EnumAnotherSample)
|
||||
var t = [1, 2]
|
||||
let uArr = cast[ptr UncheckedArray[int]](t.addr)
|
||||
testFunc(uArr)
|
||||
testFunc({})
|
||||
testFunc(proc(s:string): string = "test")
|
||||
testFunc(20, a.int32)
|
||||
testFunc(20, 2)
|
||||
testFunc(EnumSample.c)
|
||||
testFunc(EnumAnotherSample.c)
|
||||
testFunc((2, 1), "adios")
|
||||
testFunc((22.1, 1.2))
|
||||
testFunc(a.addr)
|
||||
testFunc(foo.addr)
|
||||
testFunc(aPtr.addr)
|
||||
testFunc(refFoo)
|
||||
testFunc(foo, 2, 1, refFoo)
|
||||
testFunc(a)
|
||||
testFunc(@[2, 1, 2])
|
||||
testFunc(@["hola"])
|
||||
testFunc(2, "hola", "adios")
|
||||
let arr: array[2, int] = [2, 1]
|
||||
testFunc(arr)
|
||||
testFunc(Container[int](data: 10))
|
||||
let c2 = Container2[int32, int32](data: 10, data2: 20)
|
||||
testFunc(c2)
|
||||
testFunc(Container[Container2[int32, int32]](data: c2))
|
||||
|
||||
|
||||
testFunc()
|
||||
@@ -223,3 +223,20 @@ for i in 0..100:
|
||||
var test = newSeqOfCap[uint32](1)
|
||||
test.setLen(1)
|
||||
doAssert test[0] == 0, $(test[0], i)
|
||||
|
||||
|
||||
# bug #22560
|
||||
doAssert len(newSeqOfCap[int](42)) == 0
|
||||
|
||||
block: # bug #17197
|
||||
type Matrix = seq[seq[int]]
|
||||
|
||||
proc needlemanWunsch(sequence1: string, sequence2: string, gap_penal: int8, match: int8, indel_penal: int8): bool =
|
||||
let seq2_len = sequence2.len
|
||||
|
||||
var grid: Matrix
|
||||
for i in sequence1:
|
||||
grid.add(newSeqOfCap[seq[int]](seq2_len))
|
||||
result = true
|
||||
|
||||
doAssert needlemanWunsch("ABC", "DEFG", 1, 2, 3)
|
||||
|
||||
@@ -2,8 +2,9 @@ discard """
|
||||
cmd: "nim check --warningAsError:UnreachableCode $file"
|
||||
action: "reject"
|
||||
nimout: '''
|
||||
tunreachable.nim(23, 3) Error: unreachable code after 'return' statement or '{.noReturn.}' proc [UnreachableCode]
|
||||
tunreachable.nim(30, 3) Error: unreachable code after 'return' statement or '{.noReturn.}' proc [UnreachableCode]
|
||||
tunreachable.nim(24, 3) Error: unreachable code after 'return' statement or '{.noReturn.}' proc [UnreachableCode]
|
||||
tunreachable.nim(31, 3) Error: unreachable code after 'return' statement or '{.noReturn.}' proc [UnreachableCode]
|
||||
tunreachable.nim(40, 3) Error: unreachable code after 'return' statement or '{.noReturn.}' proc [UnreachableCode]
|
||||
'''
|
||||
"""
|
||||
|
||||
@@ -30,3 +31,12 @@ proc main2() =
|
||||
echo "after"
|
||||
|
||||
main2()
|
||||
|
||||
proc main3() =
|
||||
if true:
|
||||
return
|
||||
else:
|
||||
return
|
||||
echo "after"
|
||||
|
||||
main3()
|
||||
@@ -39,7 +39,7 @@ proc foo(x: int): string {.nimcall, raises: [ValueError].} =
|
||||
|
||||
var p: MyProcType = foo #[tt.Error
|
||||
^
|
||||
type mismatch: got <proc (x: int): string{.nimcall, noSideEffect, gcsafe.}> but expected 'MyProcType = proc (x: int): string{.closure.}'
|
||||
type mismatch: got <proc (x: int): string{.nimcall, raises: [ValueError], noSideEffect, gcsafe.}> but expected 'MyProcType = proc (x: int): string{.closure.}'
|
||||
Calling convention mismatch: got '{.nimcall.}', but expected '{.closure.}'.
|
||||
.raise effects differ
|
||||
]#
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
discard """
|
||||
cmd: "nim check $file"
|
||||
errormsg: "selector must be of an ordinal type, float or string"
|
||||
errormsg: "illformed AST: case buf[pos]"
|
||||
nimout: '''
|
||||
t10735.nim(38, 5) Error: 'let' symbol requires an initialization
|
||||
t10735.nim(39, 10) Error: undeclared identifier: 'pos'
|
||||
t10735.nim(39, 9) Error: type mismatch: got <cstring, >
|
||||
t10735.nim(43, 5) Error: 'let' symbol requires an initialization
|
||||
t10735.nim(44, 10) Error: undeclared identifier: 'pos'
|
||||
t10735.nim(44, 10) Error: expression 'pos' has no type (or is ambiguous)
|
||||
t10735.nim(44, 10) Error: expression 'pos' has no type (or is ambiguous)
|
||||
t10735.nim(44, 9) Error: type mismatch: got <cstring, >
|
||||
but expected one of:
|
||||
proc `[]`(s: string; i: BackwardsIndex): char
|
||||
first type mismatch at position: 0
|
||||
@@ -26,11 +28,14 @@ proc `[]`[T](s: openArray[T]; i: BackwardsIndex): T
|
||||
first type mismatch at position: 0
|
||||
proc `[]`[T](s: var openArray[T]; i: BackwardsIndex): var T
|
||||
first type mismatch at position: 0
|
||||
template `[]`(a: WideCStringObj; idx: int): Utf16Char
|
||||
first type mismatch at position: 0
|
||||
template `[]`(s: string; i: int): char
|
||||
first type mismatch at position: 0
|
||||
|
||||
expression: `[]`(buf, pos)
|
||||
t10735.nim(39, 9) Error: selector must be of an ordinal type, float or string
|
||||
t10735.nim(44, 9) Error: expression '' has no type (or is ambiguous)
|
||||
t10735.nim(46, 3) Error: illformed AST: case buf[pos]
|
||||
'''
|
||||
joinable: false
|
||||
"""
|
||||
|
||||
35
tests/errmsgs/t22753.nim
Normal file
35
tests/errmsgs/t22753.nim
Normal file
@@ -0,0 +1,35 @@
|
||||
discard """
|
||||
cmd: "nim check --hints:off $file"
|
||||
errormsg: "type mismatch"
|
||||
nimoutFull: true
|
||||
nimout: '''
|
||||
t22753.nim(34, 13) Error: array expects two type parameters
|
||||
t22753.nim(35, 1) Error: expression 'x' has no type (or is ambiguous)
|
||||
t22753.nim(35, 1) Error: expression 'x' has no type (or is ambiguous)
|
||||
t22753.nim(35, 2) Error: type mismatch: got <>
|
||||
but expected one of:
|
||||
proc `[]=`(s: var string; i: BackwardsIndex; x: char)
|
||||
first type mismatch at position: 0
|
||||
proc `[]=`[I: Ordinal; T, S](a: T; i: I; x: sink S)
|
||||
first type mismatch at position: 0
|
||||
proc `[]=`[Idx, T; U, V: Ordinal](a: var array[Idx, T]; x: HSlice[U, V];
|
||||
b: openArray[T])
|
||||
first type mismatch at position: 0
|
||||
proc `[]=`[Idx, T](a: var array[Idx, T]; i: BackwardsIndex; x: T)
|
||||
first type mismatch at position: 0
|
||||
proc `[]=`[T, U: Ordinal](s: var string; x: HSlice[T, U]; b: string)
|
||||
first type mismatch at position: 0
|
||||
proc `[]=`[T; U, V: Ordinal](s: var seq[T]; x: HSlice[U, V]; b: openArray[T])
|
||||
first type mismatch at position: 0
|
||||
proc `[]=`[T](s: var openArray[T]; i: BackwardsIndex; x: T)
|
||||
first type mismatch at position: 0
|
||||
template `[]=`(a: WideCStringObj; idx: int; val: Utf16Char)
|
||||
first type mismatch at position: 0
|
||||
template `[]=`(s: string; i: int; val: char)
|
||||
first type mismatch at position: 0
|
||||
|
||||
expression: `[]=`(x, 0, 9)
|
||||
'''
|
||||
"""
|
||||
var x: array[3] # bug #22753
|
||||
x[0] = 9
|
||||
36
tests/exprs/t22604.nim
Normal file
36
tests/exprs/t22604.nim
Normal file
@@ -0,0 +1,36 @@
|
||||
# if
|
||||
for i in 0..<1:
|
||||
let x =
|
||||
case false
|
||||
of true:
|
||||
42
|
||||
of false:
|
||||
if true:
|
||||
continue
|
||||
else:
|
||||
raiseAssert "Won't get here"
|
||||
|
||||
# nested case
|
||||
for i in 0..<1:
|
||||
let x =
|
||||
case false
|
||||
of true:
|
||||
42
|
||||
of false:
|
||||
case true
|
||||
of true:
|
||||
continue
|
||||
of false:
|
||||
raiseAssert "Won't get here"
|
||||
|
||||
# try except
|
||||
for i in 0..<1:
|
||||
let x =
|
||||
case false
|
||||
of true:
|
||||
42
|
||||
of false:
|
||||
try:
|
||||
continue
|
||||
except:
|
||||
raiseAssert "Won't get here"
|
||||
7
tests/generics/m22373a.nim
Normal file
7
tests/generics/m22373a.nim
Normal file
@@ -0,0 +1,7 @@
|
||||
# module a for t22373
|
||||
|
||||
# original:
|
||||
type LightClientHeader* = object
|
||||
|
||||
# simplified:
|
||||
type TypeOrTemplate* = object
|
||||
18
tests/generics/m22373b.nim
Normal file
18
tests/generics/m22373b.nim
Normal file
@@ -0,0 +1,18 @@
|
||||
# module b for t22373
|
||||
|
||||
import m22373a
|
||||
|
||||
# original:
|
||||
type
|
||||
LightClientDataFork* {.pure.} = enum
|
||||
None = 0,
|
||||
Altair = 1
|
||||
template LightClientHeader*(kind: static LightClientDataFork): auto =
|
||||
when kind == LightClientDataFork.Altair:
|
||||
typedesc[m22373a.LightClientHeader]
|
||||
else:
|
||||
static: raiseAssert "Unreachable"
|
||||
|
||||
# simplified:
|
||||
template TypeOrTemplate*(num: int): untyped =
|
||||
typedesc[m22373a.TypeOrTemplate]
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user