remove more global variables in the Nim compiler
This commit is contained in:
parent
12bd1c494c
commit
669a564492
77 changed files with 679 additions and 679 deletions
|
|
@ -10,7 +10,7 @@
|
||||||
# abstract syntax tree + symbol table
|
# abstract syntax tree + symbol table
|
||||||
|
|
||||||
import
|
import
|
||||||
msgs, hashes, nversion, options, strutils, std / sha1, ropes, idents,
|
lineinfos, hashes, nversion, options, strutils, std / sha1, ropes, idents,
|
||||||
intsets, idgen
|
intsets, idgen
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,8 @@
|
||||||
# the data structures here are used in various places of the compiler.
|
# the data structures here are used in various places of the compiler.
|
||||||
|
|
||||||
import
|
import
|
||||||
ast, hashes, intsets, strutils, options, msgs, ropes, idents, rodutils
|
ast, hashes, intsets, strutils, options, lineinfos, ropes, idents, rodutils,
|
||||||
|
msgs
|
||||||
|
|
||||||
proc hashNode*(p: RootRef): Hash
|
proc hashNode*(p: RootRef): Hash
|
||||||
proc treeToYaml*(conf: ConfigRef; n: PNode, indent: int = 0, maxRecDepth: int = - 1): Rope
|
proc treeToYaml*(conf: ConfigRef; n: PNode, indent: int = 0, maxRecDepth: int = - 1): Rope
|
||||||
|
|
@ -23,44 +24,6 @@ proc typeToYaml*(conf: ConfigRef; n: PType, indent: int = 0, maxRecDepth: int =
|
||||||
proc symToYaml*(conf: ConfigRef; n: PSym, indent: int = 0, maxRecDepth: int = - 1): Rope
|
proc symToYaml*(conf: ConfigRef; n: PSym, indent: int = 0, maxRecDepth: int = - 1): Rope
|
||||||
proc lineInfoToStr*(conf: ConfigRef; info: TLineInfo): Rope
|
proc lineInfoToStr*(conf: ConfigRef; info: TLineInfo): Rope
|
||||||
|
|
||||||
# ----------------------- node sets: ---------------------------------------
|
|
||||||
proc objectSetContains*(t: TObjectSet, obj: RootRef): bool
|
|
||||||
# returns true whether n is in t
|
|
||||||
proc objectSetIncl*(t: var TObjectSet, obj: RootRef)
|
|
||||||
# include an element n in the table t
|
|
||||||
proc objectSetContainsOrIncl*(t: var TObjectSet, obj: RootRef): bool
|
|
||||||
# more are not needed ...
|
|
||||||
|
|
||||||
# ----------------------- str table -----------------------------------------
|
|
||||||
proc strTableContains*(t: TStrTable, n: PSym): bool
|
|
||||||
proc strTableAdd*(t: var TStrTable, n: PSym)
|
|
||||||
proc strTableGet*(t: TStrTable, name: PIdent): PSym
|
|
||||||
|
|
||||||
type
|
|
||||||
TTabIter*{.final.} = object # consider all fields here private
|
|
||||||
h*: Hash # current hash
|
|
||||||
|
|
||||||
proc initTabIter*(ti: var TTabIter, tab: TStrTable): PSym
|
|
||||||
proc nextIter*(ti: var TTabIter, tab: TStrTable): PSym
|
|
||||||
# usage:
|
|
||||||
# var
|
|
||||||
# i: TTabIter
|
|
||||||
# s: PSym
|
|
||||||
# s = InitTabIter(i, table)
|
|
||||||
# while s != nil:
|
|
||||||
# ...
|
|
||||||
# s = NextIter(i, table)
|
|
||||||
#
|
|
||||||
|
|
||||||
type
|
|
||||||
TIdentIter*{.final.} = object # iterator over all syms with same identifier
|
|
||||||
h*: Hash # current hash
|
|
||||||
name*: PIdent
|
|
||||||
|
|
||||||
|
|
||||||
proc initIdentIter*(ti: var TIdentIter, tab: TStrTable, s: PIdent): PSym
|
|
||||||
proc nextIdentIter*(ti: var TIdentIter, tab: TStrTable): PSym
|
|
||||||
|
|
||||||
when declared(echo):
|
when declared(echo):
|
||||||
# these are for debugging only: They are not really deprecated, but I want
|
# these are for debugging only: They are not really deprecated, but I want
|
||||||
# the warning so that release versions do not contain debugging statements:
|
# the warning so that release versions do not contain debugging statements:
|
||||||
|
|
@ -470,7 +433,7 @@ proc nextTry(h, maxHash: Hash): Hash =
|
||||||
# generates each int in range(maxHash) exactly once (see any text on
|
# generates each int in range(maxHash) exactly once (see any text on
|
||||||
# random-number generation for proof).
|
# random-number generation for proof).
|
||||||
|
|
||||||
proc objectSetContains(t: TObjectSet, obj: RootRef): bool =
|
proc objectSetContains*(t: TObjectSet, obj: RootRef): bool =
|
||||||
# returns true whether n is in t
|
# returns true whether n is in t
|
||||||
var h: Hash = hashNode(obj) and high(t.data) # start with real hash value
|
var h: Hash = hashNode(obj) and high(t.data) # start with real hash value
|
||||||
while t.data[h] != nil:
|
while t.data[h] != nil:
|
||||||
|
|
@ -494,12 +457,12 @@ proc objectSetEnlarge(t: var TObjectSet) =
|
||||||
if t.data[i] != nil: objectSetRawInsert(n, t.data[i])
|
if t.data[i] != nil: objectSetRawInsert(n, t.data[i])
|
||||||
swap(t.data, n)
|
swap(t.data, n)
|
||||||
|
|
||||||
proc objectSetIncl(t: var TObjectSet, obj: RootRef) =
|
proc objectSetIncl*(t: var TObjectSet, obj: RootRef) =
|
||||||
if mustRehash(len(t.data), t.counter): objectSetEnlarge(t)
|
if mustRehash(len(t.data), t.counter): objectSetEnlarge(t)
|
||||||
objectSetRawInsert(t.data, obj)
|
objectSetRawInsert(t.data, obj)
|
||||||
inc(t.counter)
|
inc(t.counter)
|
||||||
|
|
||||||
proc objectSetContainsOrIncl(t: var TObjectSet, obj: RootRef): bool =
|
proc objectSetContainsOrIncl*(t: var TObjectSet, obj: RootRef): bool =
|
||||||
# returns true if obj is already in the string table:
|
# returns true if obj is already in the string table:
|
||||||
var h: Hash = hashNode(obj) and high(t.data)
|
var h: Hash = hashNode(obj) and high(t.data)
|
||||||
while true:
|
while true:
|
||||||
|
|
@ -517,7 +480,7 @@ proc objectSetContainsOrIncl(t: var TObjectSet, obj: RootRef): bool =
|
||||||
inc(t.counter)
|
inc(t.counter)
|
||||||
result = false
|
result = false
|
||||||
|
|
||||||
proc strTableContains(t: TStrTable, n: PSym): bool =
|
proc strTableContains*(t: TStrTable, n: PSym): bool =
|
||||||
var h: Hash = n.name.h and high(t.data) # start with real hash value
|
var h: Hash = n.name.h and high(t.data) # start with real hash value
|
||||||
while t.data[h] != nil:
|
while t.data[h] != nil:
|
||||||
if (t.data[h] == n):
|
if (t.data[h] == n):
|
||||||
|
|
@ -573,7 +536,7 @@ proc strTableEnlarge(t: var TStrTable) =
|
||||||
if t.data[i] != nil: strTableRawInsert(n, t.data[i])
|
if t.data[i] != nil: strTableRawInsert(n, t.data[i])
|
||||||
swap(t.data, n)
|
swap(t.data, n)
|
||||||
|
|
||||||
proc strTableAdd(t: var TStrTable, n: PSym) =
|
proc strTableAdd*(t: var TStrTable, n: PSym) =
|
||||||
if mustRehash(len(t.data), t.counter): strTableEnlarge(t)
|
if mustRehash(len(t.data), t.counter): strTableEnlarge(t)
|
||||||
strTableRawInsert(t.data, n)
|
strTableRawInsert(t.data, n)
|
||||||
inc(t.counter)
|
inc(t.counter)
|
||||||
|
|
@ -609,7 +572,7 @@ proc strTableIncl*(t: var TStrTable, n: PSym; onConflictKeepOld=false): bool {.d
|
||||||
inc(t.counter)
|
inc(t.counter)
|
||||||
result = false
|
result = false
|
||||||
|
|
||||||
proc strTableGet(t: TStrTable, name: PIdent): PSym =
|
proc strTableGet*(t: TStrTable, name: PIdent): PSym =
|
||||||
var h: Hash = name.h and high(t.data)
|
var h: Hash = name.h and high(t.data)
|
||||||
while true:
|
while true:
|
||||||
result = t.data[h]
|
result = t.data[h]
|
||||||
|
|
@ -617,13 +580,13 @@ proc strTableGet(t: TStrTable, name: PIdent): PSym =
|
||||||
if result.name.id == name.id: break
|
if result.name.id == name.id: break
|
||||||
h = nextTry(h, high(t.data))
|
h = nextTry(h, high(t.data))
|
||||||
|
|
||||||
proc initIdentIter(ti: var TIdentIter, tab: TStrTable, s: PIdent): PSym =
|
|
||||||
ti.h = s.h
|
|
||||||
ti.name = s
|
|
||||||
if tab.counter == 0: result = nil
|
|
||||||
else: result = nextIdentIter(ti, tab)
|
|
||||||
|
|
||||||
proc nextIdentIter(ti: var TIdentIter, tab: TStrTable): PSym =
|
type
|
||||||
|
TIdentIter* = object # iterator over all syms with same identifier
|
||||||
|
h*: Hash # current hash
|
||||||
|
name*: PIdent
|
||||||
|
|
||||||
|
proc nextIdentIter*(ti: var TIdentIter, tab: TStrTable): PSym =
|
||||||
var h = ti.h and high(tab.data)
|
var h = ti.h and high(tab.data)
|
||||||
var start = h
|
var start = h
|
||||||
result = tab.data[h]
|
result = tab.data[h]
|
||||||
|
|
@ -636,6 +599,12 @@ proc nextIdentIter(ti: var TIdentIter, tab: TStrTable): PSym =
|
||||||
result = tab.data[h]
|
result = tab.data[h]
|
||||||
ti.h = nextTry(h, high(tab.data))
|
ti.h = nextTry(h, high(tab.data))
|
||||||
|
|
||||||
|
proc initIdentIter*(ti: var TIdentIter, tab: TStrTable, s: PIdent): PSym =
|
||||||
|
ti.h = s.h
|
||||||
|
ti.name = s
|
||||||
|
if tab.counter == 0: result = nil
|
||||||
|
else: result = nextIdentIter(ti, tab)
|
||||||
|
|
||||||
proc nextIdentExcluding*(ti: var TIdentIter, tab: TStrTable,
|
proc nextIdentExcluding*(ti: var TIdentIter, tab: TStrTable,
|
||||||
excluding: IntSet): PSym =
|
excluding: IntSet): PSym =
|
||||||
var h: Hash = ti.h and high(tab.data)
|
var h: Hash = ti.h and high(tab.data)
|
||||||
|
|
@ -659,20 +628,33 @@ proc firstIdentExcluding*(ti: var TIdentIter, tab: TStrTable, s: PIdent,
|
||||||
if tab.counter == 0: result = nil
|
if tab.counter == 0: result = nil
|
||||||
else: result = nextIdentExcluding(ti, tab, excluding)
|
else: result = nextIdentExcluding(ti, tab, excluding)
|
||||||
|
|
||||||
proc initTabIter(ti: var TTabIter, tab: TStrTable): PSym =
|
type
|
||||||
ti.h = 0 # we start by zero ...
|
TTabIter* = object
|
||||||
if tab.counter == 0:
|
h: Hash
|
||||||
result = nil # FIX 1: removed endless loop
|
|
||||||
else:
|
|
||||||
result = nextIter(ti, tab)
|
|
||||||
|
|
||||||
proc nextIter(ti: var TTabIter, tab: TStrTable): PSym =
|
proc nextIter*(ti: var TTabIter, tab: TStrTable): PSym =
|
||||||
|
# usage:
|
||||||
|
# var
|
||||||
|
# i: TTabIter
|
||||||
|
# s: PSym
|
||||||
|
# s = InitTabIter(i, table)
|
||||||
|
# while s != nil:
|
||||||
|
# ...
|
||||||
|
# s = NextIter(i, table)
|
||||||
|
#
|
||||||
result = nil
|
result = nil
|
||||||
while (ti.h <= high(tab.data)):
|
while (ti.h <= high(tab.data)):
|
||||||
result = tab.data[ti.h]
|
result = tab.data[ti.h]
|
||||||
inc(ti.h) # ... and increment by one always
|
inc(ti.h) # ... and increment by one always
|
||||||
if result != nil: break
|
if result != nil: break
|
||||||
|
|
||||||
|
proc initTabIter*(ti: var TTabIter, tab: TStrTable): PSym =
|
||||||
|
ti.h = 0
|
||||||
|
if tab.counter == 0:
|
||||||
|
result = nil
|
||||||
|
else:
|
||||||
|
result = nextIter(ti, tab)
|
||||||
|
|
||||||
iterator items*(tab: TStrTable): PSym =
|
iterator items*(tab: TStrTable): PSym =
|
||||||
var it: TTabIter
|
var it: TTabIter
|
||||||
var s = initTabIter(it, tab)
|
var s = initTabIter(it, tab)
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ template getUniqueType*(key: PType): PType = key
|
||||||
proc makeSingleLineCString*(s: string): string =
|
proc makeSingleLineCString*(s: string): string =
|
||||||
result = "\""
|
result = "\""
|
||||||
for c in items(s):
|
for c in items(s):
|
||||||
result.add(c.toCChar)
|
c.toCChar(result)
|
||||||
result.add('\"')
|
result.add('\"')
|
||||||
|
|
||||||
proc mangle*(name: string): string =
|
proc mangle*(name: string): string =
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,12 @@ import
|
||||||
nversion, nimsets, msgs, std / sha1, bitsets, idents, types,
|
nversion, nimsets, msgs, std / sha1, bitsets, idents, types,
|
||||||
ccgutils, os, ropes, math, passes, rodread, wordrecg, treetab, cgmeth,
|
ccgutils, os, ropes, math, passes, rodread, wordrecg, treetab, cgmeth,
|
||||||
condsyms, rodutils, renderer, idgen, cgendata, ccgmerge, semfold, aliases,
|
condsyms, rodutils, renderer, idgen, cgendata, ccgmerge, semfold, aliases,
|
||||||
lowerings, semparallel, tables, sets, ndi
|
lowerings, semparallel, tables, sets, ndi, lineinfos
|
||||||
|
|
||||||
import strutils except `%` # collides with ropes.`%`
|
import strutils except `%` # collides with ropes.`%`
|
||||||
|
|
||||||
from modulegraphs import ModuleGraph
|
from modulegraphs import ModuleGraph
|
||||||
from configuration import
|
from lineinfos import
|
||||||
warnGcMem, errXMustBeCompileTime, hintDependency, errGenerated, errCannotOpenFile
|
warnGcMem, errXMustBeCompileTime, hintDependency, errGenerated, errCannotOpenFile
|
||||||
import dynlib
|
import dynlib
|
||||||
|
|
||||||
|
|
@ -949,8 +949,8 @@ proc getFileHeader(conf: ConfigRef; cfile: Cfile): Rope =
|
||||||
proc genFilenames(m: BModule): Rope =
|
proc genFilenames(m: BModule): Rope =
|
||||||
discard cgsym(m, "dbgRegisterFilename")
|
discard cgsym(m, "dbgRegisterFilename")
|
||||||
result = nil
|
result = nil
|
||||||
for i in 0..<fileInfos.len:
|
for i in 0..<m.config.m.fileInfos.len:
|
||||||
result.addf("dbgRegisterFilename($1);$N", [fileInfos[i].projPath.makeCString])
|
result.addf("dbgRegisterFilename($1);$N", [m.config.m.fileInfos[i].projPath.makeCString])
|
||||||
|
|
||||||
proc genMainProc(m: BModule) =
|
proc genMainProc(m: BModule) =
|
||||||
const
|
const
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,8 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
ast, astalgo, ropes, passes, options, intsets, platform, sighashes,
|
ast, astalgo, ropes, passes, options, intsets, platform, sighashes,
|
||||||
tables, ndi
|
tables, ndi, lineinfos
|
||||||
|
|
||||||
from msgs import TLineInfo
|
|
||||||
from modulegraphs import ModuleGraph
|
from modulegraphs import ModuleGraph
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
intsets, options, ast, astalgo, msgs, idents, renderer, types, magicsys,
|
intsets, options, ast, astalgo, msgs, idents, renderer, types, magicsys,
|
||||||
sempass2, strutils, modulegraphs, configuration
|
sempass2, strutils, modulegraphs, lineinfos
|
||||||
|
|
||||||
proc genConv(n: PNode, d: PType, downcast: bool; conf: ConfigRef): PNode =
|
proc genConv(n: PNode, d: PType, downcast: bool; conf: ConfigRef): PNode =
|
||||||
var dest = skipTypes(d, abstractPtrs)
|
var dest = skipTypes(d, abstractPtrs)
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ bootSwitch(usedNoGC, defined(nogc), "--gc:none")
|
||||||
|
|
||||||
import
|
import
|
||||||
os, msgs, options, nversion, condsyms, strutils, extccomp, platform,
|
os, msgs, options, nversion, condsyms, strutils, extccomp, platform,
|
||||||
wordrecg, parseutils, nimblecmd, idents, parseopt, sequtils, configuration
|
wordrecg, parseutils, nimblecmd, idents, parseopt, sequtils, lineinfos
|
||||||
|
|
||||||
# but some have deps to imported modules. Yay.
|
# but some have deps to imported modules. Yay.
|
||||||
bootSwitch(usedTinyC, hasTinyCBackend, "-d:tinyc")
|
bootSwitch(usedTinyC, hasTinyCBackend, "-d:tinyc")
|
||||||
|
|
@ -178,11 +178,11 @@ proc processSpecificNote*(arg: string, state: TSpecialWord, pass: TCmdLinePass,
|
||||||
if i < len(arg) and (arg[i] in {':', '='}): inc(i)
|
if i < len(arg) and (arg[i] in {':', '='}): inc(i)
|
||||||
else: invalidCmdLineOption(conf, pass, orig, info)
|
else: invalidCmdLineOption(conf, pass, orig, info)
|
||||||
if state == wHint:
|
if state == wHint:
|
||||||
let x = findStr(configuration.HintsToStr, id)
|
let x = findStr(lineinfos.HintsToStr, id)
|
||||||
if x >= 0: n = TNoteKind(x + ord(hintMin))
|
if x >= 0: n = TNoteKind(x + ord(hintMin))
|
||||||
else: localError(conf, info, "unknown hint: " & id)
|
else: localError(conf, info, "unknown hint: " & id)
|
||||||
else:
|
else:
|
||||||
let x = findStr(configuration.WarningsToStr, id)
|
let x = findStr(lineinfos.WarningsToStr, id)
|
||||||
if x >= 0: n = TNoteKind(x + ord(warnMin))
|
if x >= 0: n = TNoteKind(x + ord(warnMin))
|
||||||
else: localError(conf, info, "unknown warning: " & id)
|
else: localError(conf, info, "unknown warning: " & id)
|
||||||
case substr(arg, i).normalize
|
case substr(arg, i).normalize
|
||||||
|
|
@ -324,7 +324,7 @@ proc trackDirty(conf: ConfigRef; arg: string, info: TLineInfo) =
|
||||||
if dirtyOriginalIdx.int32 >= 0:
|
if dirtyOriginalIdx.int32 >= 0:
|
||||||
msgs.setDirtyFile(conf, dirtyOriginalIdx, a[0])
|
msgs.setDirtyFile(conf, dirtyOriginalIdx, a[0])
|
||||||
|
|
||||||
gTrackPos = newLineInfo(dirtyOriginalIdx, line, column)
|
conf.m.trackPos = newLineInfo(dirtyOriginalIdx, line, column)
|
||||||
|
|
||||||
proc track(conf: ConfigRef; arg: string, info: TLineInfo) =
|
proc track(conf: ConfigRef; arg: string, info: TLineInfo) =
|
||||||
var a = arg.split(',')
|
var a = arg.split(',')
|
||||||
|
|
@ -334,7 +334,7 @@ proc track(conf: ConfigRef; arg: string, info: TLineInfo) =
|
||||||
localError(conf, info, errInvalidNumber % a[1])
|
localError(conf, info, errInvalidNumber % a[1])
|
||||||
if parseUtils.parseInt(a[2], column) <= 0:
|
if parseUtils.parseInt(a[2], column) <= 0:
|
||||||
localError(conf, info, errInvalidNumber % a[2])
|
localError(conf, info, errInvalidNumber % a[2])
|
||||||
gTrackPos = newLineInfo(conf, a[0], line, column)
|
conf.m.trackPos = newLineInfo(conf, a[0], line, column)
|
||||||
|
|
||||||
proc dynlibOverride(conf: ConfigRef; switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
|
proc dynlibOverride(conf: ConfigRef; switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
|
||||||
if pass in {passCmd2, passPP}:
|
if pass in {passCmd2, passPP}:
|
||||||
|
|
|
||||||
|
|
@ -1,182 +1,6 @@
|
||||||
#
|
## Use the module 'lineinfos' instead!
|
||||||
#
|
|
||||||
# The Nim Compiler
|
|
||||||
# (c) Copyright 2018 Andreas Rumpf
|
|
||||||
#
|
|
||||||
# See the file "copying.txt", included in this
|
|
||||||
# distribution, for details about the copyright.
|
|
||||||
#
|
|
||||||
|
|
||||||
## This module contains the rather excessive configuration object that
|
{.deprecated.}
|
||||||
## needs to be passed around to everything so that the compiler becomes
|
|
||||||
## more useful as a library.
|
|
||||||
|
|
||||||
const
|
import lineinfos
|
||||||
explanationsBaseUrl* = "https://nim-lang.org/docs/manual"
|
export lineinfos
|
||||||
|
|
||||||
type
|
|
||||||
TMsgKind* = enum
|
|
||||||
errUnknown, errInternal, errIllFormedAstX, errCannotOpenFile,
|
|
||||||
errXExpected,
|
|
||||||
errGridTableNotImplemented,
|
|
||||||
errGeneralParseError,
|
|
||||||
errNewSectionExpected,
|
|
||||||
errInvalidDirectiveX,
|
|
||||||
errGenerated,
|
|
||||||
errUser,
|
|
||||||
warnCannotOpenFile,
|
|
||||||
warnOctalEscape, warnXIsNeverRead, warnXmightNotBeenInit,
|
|
||||||
warnDeprecated, warnConfigDeprecated,
|
|
||||||
warnSmallLshouldNotBeUsed, warnUnknownMagic, warnRedefinitionOfLabel,
|
|
||||||
warnUnknownSubstitutionX, warnLanguageXNotSupported,
|
|
||||||
warnFieldXNotSupported, warnCommentXIgnored,
|
|
||||||
warnTypelessParam,
|
|
||||||
warnUseBase, warnWriteToForeignHeap, warnUnsafeCode,
|
|
||||||
warnEachIdentIsTuple, warnShadowIdent,
|
|
||||||
warnProveInit, warnProveField, warnProveIndex, warnGcUnsafe, warnGcUnsafe2,
|
|
||||||
warnUninit, warnGcMem, warnDestructor, warnLockLevel, warnResultShadowed,
|
|
||||||
warnInconsistentSpacing, warnUser,
|
|
||||||
hintSuccess, hintSuccessX,
|
|
||||||
hintLineTooLong, hintXDeclaredButNotUsed, hintConvToBaseNotNeeded,
|
|
||||||
hintConvFromXtoItselfNotNeeded, hintExprAlwaysX, hintQuitCalled,
|
|
||||||
hintProcessing, hintCodeBegin, hintCodeEnd, hintConf, hintPath,
|
|
||||||
hintConditionAlwaysTrue, hintName, hintPattern,
|
|
||||||
hintExecuting, hintLinking, hintDependency,
|
|
||||||
hintSource, hintPerformance, hintStackTrace, hintGCStats,
|
|
||||||
hintUser, hintUserRaw
|
|
||||||
|
|
||||||
const
|
|
||||||
MsgKindToStr*: array[TMsgKind, string] = [
|
|
||||||
errUnknown: "unknown error",
|
|
||||||
errInternal: "internal error: $1",
|
|
||||||
errIllFormedAstX: "illformed AST: $1",
|
|
||||||
errCannotOpenFile: "cannot open '$1'",
|
|
||||||
errXExpected: "'$1' expected",
|
|
||||||
errGridTableNotImplemented: "grid table is not implemented",
|
|
||||||
errGeneralParseError: "general parse error",
|
|
||||||
errNewSectionExpected: "new section expected",
|
|
||||||
errInvalidDirectiveX: "invalid directive: '$1'",
|
|
||||||
errGenerated: "$1",
|
|
||||||
errUser: "$1",
|
|
||||||
warnCannotOpenFile: "cannot open '$1'",
|
|
||||||
warnOctalEscape: "octal escape sequences do not exist; leading zero is ignored",
|
|
||||||
warnXIsNeverRead: "'$1' is never read",
|
|
||||||
warnXmightNotBeenInit: "'$1' might not have been initialized",
|
|
||||||
warnDeprecated: "$1 is deprecated",
|
|
||||||
warnConfigDeprecated: "config file '$1' is deprecated",
|
|
||||||
warnSmallLshouldNotBeUsed: "'l' should not be used as an identifier; may look like '1' (one)",
|
|
||||||
warnUnknownMagic: "unknown magic '$1' might crash the compiler",
|
|
||||||
warnRedefinitionOfLabel: "redefinition of label '$1'",
|
|
||||||
warnUnknownSubstitutionX: "unknown substitution '$1'",
|
|
||||||
warnLanguageXNotSupported: "language '$1' not supported",
|
|
||||||
warnFieldXNotSupported: "field '$1' not supported",
|
|
||||||
warnCommentXIgnored: "comment '$1' ignored",
|
|
||||||
warnTypelessParam: "'$1' has no type. Typeless parameters are deprecated; only allowed for 'template'",
|
|
||||||
warnUseBase: "use {.base.} for base methods; baseless methods are deprecated",
|
|
||||||
warnWriteToForeignHeap: "write to foreign heap",
|
|
||||||
warnUnsafeCode: "unsafe code: '$1'",
|
|
||||||
warnEachIdentIsTuple: "each identifier is a tuple",
|
|
||||||
warnShadowIdent: "shadowed identifier: '$1'",
|
|
||||||
warnProveInit: "Cannot prove that '$1' is initialized. This will become a compile time error in the future.",
|
|
||||||
warnProveField: "cannot prove that field '$1' is accessible",
|
|
||||||
warnProveIndex: "cannot prove index '$1' is valid",
|
|
||||||
warnGcUnsafe: "not GC-safe: '$1'",
|
|
||||||
warnGcUnsafe2: "$1",
|
|
||||||
warnUninit: "'$1' might not have been initialized",
|
|
||||||
warnGcMem: "'$1' uses GC'ed memory",
|
|
||||||
warnDestructor: "usage of a type with a destructor in a non destructible context. This will become a compile time error in the future.",
|
|
||||||
warnLockLevel: "$1",
|
|
||||||
warnResultShadowed: "Special variable 'result' is shadowed.",
|
|
||||||
warnInconsistentSpacing: "Number of spaces around '$#' is not consistent",
|
|
||||||
warnUser: "$1",
|
|
||||||
hintSuccess: "operation successful",
|
|
||||||
hintSuccessX: "operation successful ($# lines compiled; $# sec total; $#; $#)",
|
|
||||||
hintLineTooLong: "line too long",
|
|
||||||
hintXDeclaredButNotUsed: "'$1' is declared but not used",
|
|
||||||
hintConvToBaseNotNeeded: "conversion to base object is not needed",
|
|
||||||
hintConvFromXtoItselfNotNeeded: "conversion from $1 to itself is pointless",
|
|
||||||
hintExprAlwaysX: "expression evaluates always to '$1'",
|
|
||||||
hintQuitCalled: "quit() called",
|
|
||||||
hintProcessing: "$1",
|
|
||||||
hintCodeBegin: "generated code listing:",
|
|
||||||
hintCodeEnd: "end of listing",
|
|
||||||
hintConf: "used config file '$1'",
|
|
||||||
hintPath: "added path: '$1'",
|
|
||||||
hintConditionAlwaysTrue: "condition is always true: '$1'",
|
|
||||||
hintName: "name should be: '$1'",
|
|
||||||
hintPattern: "$1",
|
|
||||||
hintExecuting: "$1",
|
|
||||||
hintLinking: "",
|
|
||||||
hintDependency: "$1",
|
|
||||||
hintSource: "$1",
|
|
||||||
hintPerformance: "$1",
|
|
||||||
hintStackTrace: "$1",
|
|
||||||
hintGCStats: "$1",
|
|
||||||
hintUser: "$1",
|
|
||||||
hintUserRaw: "$1"]
|
|
||||||
|
|
||||||
const
|
|
||||||
WarningsToStr* = ["CannotOpenFile", "OctalEscape",
|
|
||||||
"XIsNeverRead", "XmightNotBeenInit",
|
|
||||||
"Deprecated", "ConfigDeprecated",
|
|
||||||
"SmallLshouldNotBeUsed", "UnknownMagic",
|
|
||||||
"RedefinitionOfLabel", "UnknownSubstitutionX",
|
|
||||||
"LanguageXNotSupported", "FieldXNotSupported",
|
|
||||||
"CommentXIgnored",
|
|
||||||
"TypelessParam", "UseBase", "WriteToForeignHeap",
|
|
||||||
"UnsafeCode", "EachIdentIsTuple", "ShadowIdent",
|
|
||||||
"ProveInit", "ProveField", "ProveIndex", "GcUnsafe", "GcUnsafe2", "Uninit",
|
|
||||||
"GcMem", "Destructor", "LockLevel", "ResultShadowed",
|
|
||||||
"Spacing", "User"]
|
|
||||||
|
|
||||||
HintsToStr* = ["Success", "SuccessX", "LineTooLong",
|
|
||||||
"XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded",
|
|
||||||
"ExprAlwaysX", "QuitCalled", "Processing", "CodeBegin", "CodeEnd", "Conf",
|
|
||||||
"Path", "CondTrue", "Name", "Pattern", "Exec", "Link", "Dependency",
|
|
||||||
"Source", "Performance", "StackTrace", "GCStats",
|
|
||||||
"User", "UserRaw"]
|
|
||||||
|
|
||||||
const
|
|
||||||
fatalMin* = errUnknown
|
|
||||||
fatalMax* = errInternal
|
|
||||||
errMin* = errUnknown
|
|
||||||
errMax* = errUser
|
|
||||||
warnMin* = warnCannotOpenFile
|
|
||||||
warnMax* = pred(hintSuccess)
|
|
||||||
hintMin* = hintSuccess
|
|
||||||
hintMax* = high(TMsgKind)
|
|
||||||
|
|
||||||
static:
|
|
||||||
doAssert HintsToStr.len == ord(hintMax) - ord(hintMin) + 1
|
|
||||||
doAssert WarningsToStr.len == ord(warnMax) - ord(warnMin) + 1
|
|
||||||
|
|
||||||
type
|
|
||||||
TNoteKind* = range[warnMin..hintMax] # "notes" are warnings or hints
|
|
||||||
TNoteKinds* = set[TNoteKind]
|
|
||||||
|
|
||||||
const
|
|
||||||
NotesVerbosity*: array[0..3, TNoteKinds] = [
|
|
||||||
{low(TNoteKind)..high(TNoteKind)} - {warnShadowIdent, warnUninit,
|
|
||||||
warnProveField, warnProveIndex,
|
|
||||||
warnGcUnsafe,
|
|
||||||
hintSuccessX, hintPath, hintConf,
|
|
||||||
hintProcessing, hintPattern,
|
|
||||||
hintDependency,
|
|
||||||
hintExecuting, hintLinking,
|
|
||||||
hintCodeBegin, hintCodeEnd,
|
|
||||||
hintSource, hintStackTrace,
|
|
||||||
hintGCStats},
|
|
||||||
{low(TNoteKind)..high(TNoteKind)} - {warnShadowIdent, warnUninit,
|
|
||||||
warnProveField, warnProveIndex,
|
|
||||||
warnGcUnsafe,
|
|
||||||
hintPath,
|
|
||||||
hintDependency,
|
|
||||||
hintCodeBegin, hintCodeEnd,
|
|
||||||
hintSource, hintStackTrace,
|
|
||||||
hintGCStats},
|
|
||||||
{low(TNoteKind)..high(TNoteKind)} - {hintStackTrace, warnUninit},
|
|
||||||
{low(TNoteKind)..high(TNoteKind)}]
|
|
||||||
|
|
||||||
const
|
|
||||||
errXMustBeCompileTime* = "'$1' can only be used in compile-time context"
|
|
||||||
errArgsNeedRunOption* = "arguments can only be given if the '--run' option is selected"
|
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ Remarks: Rule 1.2 is not yet implemented because ``sink`` is currently
|
||||||
import
|
import
|
||||||
intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees,
|
intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees,
|
||||||
strutils, options, dfa, lowerings, rodread, tables, modulegraphs,
|
strutils, options, dfa, lowerings, rodread, tables, modulegraphs,
|
||||||
configuration
|
lineinfos
|
||||||
|
|
||||||
const
|
const
|
||||||
InterestingSyms = {skVar, skResult, skLet}
|
InterestingSyms = {skVar, skResult, skLet}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
## "A Graph–Free Approach to Data–Flow Analysis" by Markus Mohnen.
|
## "A Graph–Free Approach to Data–Flow Analysis" by Markus Mohnen.
|
||||||
## https://link.springer.com/content/pdf/10.1007/3-540-45937-5_6.pdf
|
## https://link.springer.com/content/pdf/10.1007/3-540-45937-5_6.pdf
|
||||||
|
|
||||||
import ast, astalgo, types, intsets, tables, msgs, options
|
import ast, astalgo, types, intsets, tables, msgs, options, lineinfos
|
||||||
|
|
||||||
type
|
type
|
||||||
InstrKind* = enum
|
InstrKind* = enum
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import
|
||||||
wordrecg, syntaxes, renderer, lexer, packages/docutils/rstast,
|
wordrecg, syntaxes, renderer, lexer, packages/docutils/rstast,
|
||||||
packages/docutils/rst, packages/docutils/rstgen, times,
|
packages/docutils/rst, packages/docutils/rstgen, times,
|
||||||
packages/docutils/highlite, sempass2, json, xmltree, cgi,
|
packages/docutils/highlite, sempass2, json, xmltree, cgi,
|
||||||
typesrenderer, astalgo, modulepaths, configuration
|
typesrenderer, astalgo, modulepaths, lineinfos
|
||||||
|
|
||||||
type
|
type
|
||||||
TSections = array[TSymKind, Rope]
|
TSections = array[TSymKind, Rope]
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
# semantic checking.
|
# semantic checking.
|
||||||
|
|
||||||
import
|
import
|
||||||
os, options, ast, astalgo, msgs, ropes, idents, passes, docgen
|
os, options, ast, astalgo, msgs, ropes, idents, passes, docgen, lineinfos
|
||||||
|
|
||||||
from modulegraphs import ModuleGraph
|
from modulegraphs import ModuleGraph
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
strutils, options, ast, astalgo, msgs, os, idents, wordrecg, renderer,
|
strutils, options, ast, astalgo, msgs, os, idents, wordrecg, renderer,
|
||||||
rodread
|
rodread, lineinfos
|
||||||
|
|
||||||
type
|
type
|
||||||
TemplCtx = object
|
TemplCtx = object
|
||||||
|
|
@ -114,7 +114,6 @@ proc evalTemplateArgs(n: PNode, s: PSym; conf: ConfigRef; fromHlo: bool): PNode
|
||||||
|
|
||||||
# to prevent endless recursion in template instantiation
|
# to prevent endless recursion in template instantiation
|
||||||
const evalTemplateLimit* = 1000
|
const evalTemplateLimit* = 1000
|
||||||
var evalTemplateCounter* = 0 # XXX remove this global
|
|
||||||
|
|
||||||
proc wrapInComesFrom*(info: TLineInfo; sym: PSym; res: PNode): PNode =
|
proc wrapInComesFrom*(info: TLineInfo; sym: PSym; res: PNode): PNode =
|
||||||
when true:
|
when true:
|
||||||
|
|
@ -140,8 +139,8 @@ proc wrapInComesFrom*(info: TLineInfo; sym: PSym; res: PNode): PNode =
|
||||||
|
|
||||||
proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym;
|
proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym;
|
||||||
conf: ConfigRef; fromHlo=false): PNode =
|
conf: ConfigRef; fromHlo=false): PNode =
|
||||||
inc(evalTemplateCounter)
|
inc(conf.evalTemplateCounter)
|
||||||
if evalTemplateCounter > evalTemplateLimit:
|
if conf.evalTemplateCounter > evalTemplateLimit:
|
||||||
globalError(conf, n.info, errTemplateInstantiationTooNested)
|
globalError(conf, n.info, errTemplateInstantiationTooNested)
|
||||||
result = n
|
result = n
|
||||||
|
|
||||||
|
|
@ -170,5 +169,5 @@ proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym;
|
||||||
evalTemplateAux(body.sons[i], args, ctx, result)
|
evalTemplateAux(body.sons[i], args, ctx, result)
|
||||||
result.flags.incl nfFromTemplate
|
result.flags.incl nfFromTemplate
|
||||||
result = wrapInComesFrom(n.info, tmpl, result)
|
result = wrapInComesFrom(n.info, tmpl, result)
|
||||||
dec(evalTemplateCounter)
|
dec(conf.evalTemplateCounter)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,12 @@
|
||||||
|
|
||||||
# Module providing functions for calling the different external C compilers
|
# Module providing functions for calling the different external C compilers
|
||||||
# Uses some hard-wired facts about each C/C++ compiler, plus options read
|
# Uses some hard-wired facts about each C/C++ compiler, plus options read
|
||||||
# from a configuration file, to provide generalized procedures to compile
|
# from a lineinfos file, to provide generalized procedures to compile
|
||||||
# nim files.
|
# nim files.
|
||||||
|
|
||||||
import
|
import
|
||||||
ropes, os, strutils, osproc, platform, condsyms, options, msgs,
|
ropes, os, strutils, osproc, platform, condsyms, options, msgs,
|
||||||
configuration, std / sha1, streams
|
lineinfos, std / sha1, streams
|
||||||
|
|
||||||
type
|
type
|
||||||
TInfoCCProp* = enum # properties of the C compiler:
|
TInfoCCProp* = enum # properties of the C compiler:
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options,
|
llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options,
|
||||||
renderer, filters
|
renderer, filters, lineinfos
|
||||||
|
|
||||||
type
|
type
|
||||||
TParseState = enum
|
TParseState = enum
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@
|
||||||
|
|
||||||
## Module that implements ``gorge`` for the compiler.
|
## Module that implements ``gorge`` for the compiler.
|
||||||
|
|
||||||
import msgs, std / sha1, os, osproc, streams, strutils, options
|
import msgs, std / sha1, os, osproc, streams, strutils, options,
|
||||||
|
lineinfos
|
||||||
|
|
||||||
proc readOutput(p: Process): (string, int) =
|
proc readOutput(p: Process): (string, int) =
|
||||||
result[0] = ""
|
result[0] = ""
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
## This module implements the 'implies' relation for guards.
|
## This module implements the 'implies' relation for guards.
|
||||||
|
|
||||||
import ast, astalgo, msgs, magicsys, nimsets, trees, types, renderer, idents,
|
import ast, astalgo, msgs, magicsys, nimsets, trees, types, renderer, idents,
|
||||||
saturate, modulegraphs, options, configuration
|
saturate, modulegraphs, options, lineinfos
|
||||||
|
|
||||||
const
|
const
|
||||||
someEq = {mEqI, mEqF64, mEqEnum, mEqCh, mEqB, mEqRef, mEqProc,
|
someEq = {mEqI, mEqF64, mEqEnum, mEqCh, mEqB, mEqRef, mEqProc,
|
||||||
|
|
|
||||||
|
|
@ -43,8 +43,8 @@ proc applyPatterns(c: PContext, n: PNode): PNode =
|
||||||
if not isNil(x):
|
if not isNil(x):
|
||||||
assert x.kind in {nkStmtList, nkCall}
|
assert x.kind in {nkStmtList, nkCall}
|
||||||
# better be safe than sorry, so check evalTemplateCounter too:
|
# better be safe than sorry, so check evalTemplateCounter too:
|
||||||
inc(evalTemplateCounter)
|
inc(c.config.evalTemplateCounter)
|
||||||
if evalTemplateCounter > evalTemplateLimit:
|
if c.config.evalTemplateCounter > evalTemplateLimit:
|
||||||
globalError(c.config, n.info, "template instantiation too nested")
|
globalError(c.config, n.info, "template instantiation too nested")
|
||||||
# deactivate this pattern:
|
# deactivate this pattern:
|
||||||
c.patterns[i] = nil
|
c.patterns[i] = nil
|
||||||
|
|
@ -54,7 +54,7 @@ proc applyPatterns(c: PContext, n: PNode): PNode =
|
||||||
result = flattenStmts(x)
|
result = flattenStmts(x)
|
||||||
else:
|
else:
|
||||||
result = evalPattern(c, x, result)
|
result = evalPattern(c, x, result)
|
||||||
dec(evalTemplateCounter)
|
dec(c.config.evalTemplateCounter)
|
||||||
# activate this pattern again:
|
# activate this pattern again:
|
||||||
c.patterns[i] = pattern
|
c.patterns[i] = pattern
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
intsets, strutils, os, ast, astalgo, msgs, options, idents, rodread, lookups,
|
intsets, strutils, os, ast, astalgo, msgs, options, idents, rodread, lookups,
|
||||||
semdata, passes, renderer, modulepaths, sigmatch, configuration
|
semdata, passes, renderer, modulepaths, sigmatch, lineinfos
|
||||||
|
|
||||||
proc evalImport*(c: PContext, n: PNode): PNode
|
proc evalImport*(c: PContext, n: PNode): PNode
|
||||||
proc evalFrom*(c: PContext, n: PNode): PNode
|
proc evalFrom*(c: PContext, n: PNode): PNode
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ import
|
||||||
ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp, options,
|
ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp, options,
|
||||||
nversion, nimsets, msgs, std / sha1, bitsets, idents, types, os, tables,
|
nversion, nimsets, msgs, std / sha1, bitsets, idents, types, os, tables,
|
||||||
times, ropes, math, passes, ccgutils, wordrecg, renderer, rodread, rodutils,
|
times, ropes, math, passes, ccgutils, wordrecg, renderer, rodread, rodutils,
|
||||||
intsets, cgmeth, lowerings, sighashes, configuration
|
intsets, cgmeth, lowerings, sighashes, lineinfos
|
||||||
|
|
||||||
from modulegraphs import ModuleGraph
|
from modulegraphs import ModuleGraph
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
import
|
import
|
||||||
intsets, strutils, options, ast, astalgo, trees, treetab, msgs, os,
|
intsets, strutils, options, ast, astalgo, trees, treetab, msgs, os,
|
||||||
idents, renderer, types, magicsys, rodread, lowerings, tables,
|
idents, renderer, types, magicsys, rodread, lowerings, tables,
|
||||||
modulegraphs
|
modulegraphs, lineinfos
|
||||||
|
|
||||||
discard """
|
discard """
|
||||||
The basic approach is that captured vars need to be put on the heap and
|
The basic approach is that captured vars need to be put on the heap and
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
hashes, options, msgs, strutils, platform, idents, nimlexbase, llstream,
|
hashes, options, msgs, strutils, platform, idents, nimlexbase, llstream,
|
||||||
wordrecg, configuration
|
wordrecg, lineinfos
|
||||||
|
|
||||||
const
|
const
|
||||||
MaxLineLength* = 80 # lines longer than this lead to a warning
|
MaxLineLength* = 80 # lines longer than this lead to a warning
|
||||||
|
|
@ -273,10 +273,10 @@ template tokenBegin(tok, pos) {.dirty.} =
|
||||||
template tokenEnd(tok, pos) {.dirty.} =
|
template tokenEnd(tok, pos) {.dirty.} =
|
||||||
when defined(nimsuggest):
|
when defined(nimsuggest):
|
||||||
let colB = getColNumber(L, pos)+1
|
let colB = getColNumber(L, pos)+1
|
||||||
if L.fileIdx == gTrackPos.fileIndex and gTrackPos.col in colA..colB and
|
if L.fileIdx == L.config.m.trackPos.fileIndex and L.config.m.trackPos.col in colA..colB and
|
||||||
L.lineNumber == gTrackPos.line.int and L.config.ideCmd in {ideSug, ideCon}:
|
L.lineNumber == L.config.m.trackPos.line.int and L.config.ideCmd in {ideSug, ideCon}:
|
||||||
L.cursor = CursorPosition.InToken
|
L.cursor = CursorPosition.InToken
|
||||||
gTrackPos.col = colA.int16
|
L.config.m.trackPos.col = colA.int16
|
||||||
colA = 0
|
colA = 0
|
||||||
when defined(nimpretty):
|
when defined(nimpretty):
|
||||||
tok.offsetB = L.offsetBase + pos
|
tok.offsetB = L.offsetBase + pos
|
||||||
|
|
@ -284,10 +284,10 @@ template tokenEnd(tok, pos) {.dirty.} =
|
||||||
template tokenEndIgnore(tok, pos) =
|
template tokenEndIgnore(tok, pos) =
|
||||||
when defined(nimsuggest):
|
when defined(nimsuggest):
|
||||||
let colB = getColNumber(L, pos)
|
let colB = getColNumber(L, pos)
|
||||||
if L.fileIdx == gTrackPos.fileIndex and gTrackPos.col in colA..colB and
|
if L.fileIdx == L.config.m.trackPos.fileIndex and L.config.m.trackPos.col in colA..colB and
|
||||||
L.lineNumber == gTrackPos.line.int and L.config.ideCmd in {ideSug, ideCon}:
|
L.lineNumber == L.config.m.trackPos.line.int and L.config.ideCmd in {ideSug, ideCon}:
|
||||||
gTrackPos.fileIndex = trackPosInvalidFileIdx
|
L.config.m.trackPos.fileIndex = trackPosInvalidFileIdx
|
||||||
gTrackPos.line = 0'u16
|
L.config.m.trackPos.line = 0'u16
|
||||||
colA = 0
|
colA = 0
|
||||||
when defined(nimpretty):
|
when defined(nimpretty):
|
||||||
tok.offsetB = L.offsetBase + pos
|
tok.offsetB = L.offsetBase + pos
|
||||||
|
|
@ -298,11 +298,11 @@ template tokenEndPrevious(tok, pos) =
|
||||||
# to the token that came before that, but only if we haven't detected
|
# to the token that came before that, but only if we haven't detected
|
||||||
# the cursor in a string literal or comment:
|
# the cursor in a string literal or comment:
|
||||||
let colB = getColNumber(L, pos)
|
let colB = getColNumber(L, pos)
|
||||||
if L.fileIdx == gTrackPos.fileIndex and gTrackPos.col in colA..colB and
|
if L.fileIdx == L.config.m.trackPos.fileIndex and L.config.m.trackPos.col in colA..colB and
|
||||||
L.lineNumber == gTrackPos.line.int and L.config.ideCmd in {ideSug, ideCon}:
|
L.lineNumber == L.config.m.trackPos.line.int and L.config.ideCmd in {ideSug, ideCon}:
|
||||||
L.cursor = CursorPosition.BeforeToken
|
L.cursor = CursorPosition.BeforeToken
|
||||||
gTrackPos = L.previousToken
|
L.config.m.trackPos = L.previousToken
|
||||||
gTrackPosAttached = true
|
L.config.m.trackPosAttached = true
|
||||||
colA = 0
|
colA = 0
|
||||||
when defined(nimpretty):
|
when defined(nimpretty):
|
||||||
tok.offsetB = L.offsetBase + pos
|
tok.offsetB = L.offsetBase + pos
|
||||||
|
|
@ -1121,9 +1121,9 @@ proc rawGetTok*(L: var TLexer, tok: var TToken) =
|
||||||
else:
|
else:
|
||||||
tok.tokType = tkParLe
|
tok.tokType = tkParLe
|
||||||
when defined(nimsuggest):
|
when defined(nimsuggest):
|
||||||
if L.fileIdx == gTrackPos.fileIndex and tok.col < gTrackPos.col and
|
if L.fileIdx == L.config.m.trackPos.fileIndex and tok.col < L.config.m.trackPos.col and
|
||||||
tok.line == gTrackPos.line.int and L.config.ideCmd == ideCon:
|
tok.line == L.config.m.trackPos.line.int and L.config.ideCmd == ideCon:
|
||||||
gTrackPos.col = tok.col.int16
|
L.config.m.trackPos.col = tok.col.int16
|
||||||
of ')':
|
of ')':
|
||||||
tok.tokType = tkParRi
|
tok.tokType = tkParRi
|
||||||
inc(L.bufpos)
|
inc(L.bufpos)
|
||||||
|
|
@ -1142,11 +1142,11 @@ proc rawGetTok*(L: var TLexer, tok: var TToken) =
|
||||||
inc(L.bufpos)
|
inc(L.bufpos)
|
||||||
of '.':
|
of '.':
|
||||||
when defined(nimsuggest):
|
when defined(nimsuggest):
|
||||||
if L.fileIdx == gTrackPos.fileIndex and tok.col+1 == gTrackPos.col and
|
if L.fileIdx == L.config.m.trackPos.fileIndex and tok.col+1 == L.config.m.trackPos.col and
|
||||||
tok.line == gTrackPos.line.int and L.config.ideCmd == ideSug:
|
tok.line == L.config.m.trackPos.line.int and L.config.ideCmd == ideSug:
|
||||||
tok.tokType = tkDot
|
tok.tokType = tkDot
|
||||||
L.cursor = CursorPosition.InToken
|
L.cursor = CursorPosition.InToken
|
||||||
gTrackPos.col = tok.col.int16
|
L.config.m.trackPos.col = tok.col.int16
|
||||||
inc(L.bufpos)
|
inc(L.bufpos)
|
||||||
atTokenEnd()
|
atTokenEnd()
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
intsets, strutils, options, ast, astalgo, msgs,
|
intsets, strutils, options, ast, astalgo, msgs,
|
||||||
idents, renderer, types, lowerings
|
idents, renderer, types, lowerings, lineinfos
|
||||||
|
|
||||||
from pragmas import getPragmaVal
|
from pragmas import getPragmaVal
|
||||||
from wordrecg import wLiftLocals
|
from wordrecg import wLiftLocals
|
||||||
|
|
|
||||||
264
compiler/lineinfos.nim
Normal file
264
compiler/lineinfos.nim
Normal file
|
|
@ -0,0 +1,264 @@
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# The Nim Compiler
|
||||||
|
# (c) Copyright 2018 Andreas Rumpf
|
||||||
|
#
|
||||||
|
# See the file "copying.txt", included in this
|
||||||
|
# distribution, for details about the copyright.
|
||||||
|
#
|
||||||
|
|
||||||
|
## This module contains the ``TMsgKind`` enum as well as the
|
||||||
|
## ``TLineInfo`` object.
|
||||||
|
|
||||||
|
import ropes, tables
|
||||||
|
|
||||||
|
const
|
||||||
|
explanationsBaseUrl* = "https://nim-lang.org/docs/manual"
|
||||||
|
|
||||||
|
type
|
||||||
|
TMsgKind* = enum
|
||||||
|
errUnknown, errInternal, errIllFormedAstX, errCannotOpenFile,
|
||||||
|
errXExpected,
|
||||||
|
errGridTableNotImplemented,
|
||||||
|
errGeneralParseError,
|
||||||
|
errNewSectionExpected,
|
||||||
|
errInvalidDirectiveX,
|
||||||
|
errGenerated,
|
||||||
|
errUser,
|
||||||
|
warnCannotOpenFile,
|
||||||
|
warnOctalEscape, warnXIsNeverRead, warnXmightNotBeenInit,
|
||||||
|
warnDeprecated, warnConfigDeprecated,
|
||||||
|
warnSmallLshouldNotBeUsed, warnUnknownMagic, warnRedefinitionOfLabel,
|
||||||
|
warnUnknownSubstitutionX, warnLanguageXNotSupported,
|
||||||
|
warnFieldXNotSupported, warnCommentXIgnored,
|
||||||
|
warnTypelessParam,
|
||||||
|
warnUseBase, warnWriteToForeignHeap, warnUnsafeCode,
|
||||||
|
warnEachIdentIsTuple, warnShadowIdent,
|
||||||
|
warnProveInit, warnProveField, warnProveIndex, warnGcUnsafe, warnGcUnsafe2,
|
||||||
|
warnUninit, warnGcMem, warnDestructor, warnLockLevel, warnResultShadowed,
|
||||||
|
warnInconsistentSpacing, warnUser,
|
||||||
|
hintSuccess, hintSuccessX,
|
||||||
|
hintLineTooLong, hintXDeclaredButNotUsed, hintConvToBaseNotNeeded,
|
||||||
|
hintConvFromXtoItselfNotNeeded, hintExprAlwaysX, hintQuitCalled,
|
||||||
|
hintProcessing, hintCodeBegin, hintCodeEnd, hintConf, hintPath,
|
||||||
|
hintConditionAlwaysTrue, hintName, hintPattern,
|
||||||
|
hintExecuting, hintLinking, hintDependency,
|
||||||
|
hintSource, hintPerformance, hintStackTrace, hintGCStats,
|
||||||
|
hintUser, hintUserRaw
|
||||||
|
|
||||||
|
const
|
||||||
|
MsgKindToStr*: array[TMsgKind, string] = [
|
||||||
|
errUnknown: "unknown error",
|
||||||
|
errInternal: "internal error: $1",
|
||||||
|
errIllFormedAstX: "illformed AST: $1",
|
||||||
|
errCannotOpenFile: "cannot open '$1'",
|
||||||
|
errXExpected: "'$1' expected",
|
||||||
|
errGridTableNotImplemented: "grid table is not implemented",
|
||||||
|
errGeneralParseError: "general parse error",
|
||||||
|
errNewSectionExpected: "new section expected",
|
||||||
|
errInvalidDirectiveX: "invalid directive: '$1'",
|
||||||
|
errGenerated: "$1",
|
||||||
|
errUser: "$1",
|
||||||
|
warnCannotOpenFile: "cannot open '$1'",
|
||||||
|
warnOctalEscape: "octal escape sequences do not exist; leading zero is ignored",
|
||||||
|
warnXIsNeverRead: "'$1' is never read",
|
||||||
|
warnXmightNotBeenInit: "'$1' might not have been initialized",
|
||||||
|
warnDeprecated: "$1 is deprecated",
|
||||||
|
warnConfigDeprecated: "config file '$1' is deprecated",
|
||||||
|
warnSmallLshouldNotBeUsed: "'l' should not be used as an identifier; may look like '1' (one)",
|
||||||
|
warnUnknownMagic: "unknown magic '$1' might crash the compiler",
|
||||||
|
warnRedefinitionOfLabel: "redefinition of label '$1'",
|
||||||
|
warnUnknownSubstitutionX: "unknown substitution '$1'",
|
||||||
|
warnLanguageXNotSupported: "language '$1' not supported",
|
||||||
|
warnFieldXNotSupported: "field '$1' not supported",
|
||||||
|
warnCommentXIgnored: "comment '$1' ignored",
|
||||||
|
warnTypelessParam: "'$1' has no type. Typeless parameters are deprecated; only allowed for 'template'",
|
||||||
|
warnUseBase: "use {.base.} for base methods; baseless methods are deprecated",
|
||||||
|
warnWriteToForeignHeap: "write to foreign heap",
|
||||||
|
warnUnsafeCode: "unsafe code: '$1'",
|
||||||
|
warnEachIdentIsTuple: "each identifier is a tuple",
|
||||||
|
warnShadowIdent: "shadowed identifier: '$1'",
|
||||||
|
warnProveInit: "Cannot prove that '$1' is initialized. This will become a compile time error in the future.",
|
||||||
|
warnProveField: "cannot prove that field '$1' is accessible",
|
||||||
|
warnProveIndex: "cannot prove index '$1' is valid",
|
||||||
|
warnGcUnsafe: "not GC-safe: '$1'",
|
||||||
|
warnGcUnsafe2: "$1",
|
||||||
|
warnUninit: "'$1' might not have been initialized",
|
||||||
|
warnGcMem: "'$1' uses GC'ed memory",
|
||||||
|
warnDestructor: "usage of a type with a destructor in a non destructible context. This will become a compile time error in the future.",
|
||||||
|
warnLockLevel: "$1",
|
||||||
|
warnResultShadowed: "Special variable 'result' is shadowed.",
|
||||||
|
warnInconsistentSpacing: "Number of spaces around '$#' is not consistent",
|
||||||
|
warnUser: "$1",
|
||||||
|
hintSuccess: "operation successful",
|
||||||
|
hintSuccessX: "operation successful ($# lines compiled; $# sec total; $#; $#)",
|
||||||
|
hintLineTooLong: "line too long",
|
||||||
|
hintXDeclaredButNotUsed: "'$1' is declared but not used",
|
||||||
|
hintConvToBaseNotNeeded: "conversion to base object is not needed",
|
||||||
|
hintConvFromXtoItselfNotNeeded: "conversion from $1 to itself is pointless",
|
||||||
|
hintExprAlwaysX: "expression evaluates always to '$1'",
|
||||||
|
hintQuitCalled: "quit() called",
|
||||||
|
hintProcessing: "$1",
|
||||||
|
hintCodeBegin: "generated code listing:",
|
||||||
|
hintCodeEnd: "end of listing",
|
||||||
|
hintConf: "used config file '$1'",
|
||||||
|
hintPath: "added path: '$1'",
|
||||||
|
hintConditionAlwaysTrue: "condition is always true: '$1'",
|
||||||
|
hintName: "name should be: '$1'",
|
||||||
|
hintPattern: "$1",
|
||||||
|
hintExecuting: "$1",
|
||||||
|
hintLinking: "",
|
||||||
|
hintDependency: "$1",
|
||||||
|
hintSource: "$1",
|
||||||
|
hintPerformance: "$1",
|
||||||
|
hintStackTrace: "$1",
|
||||||
|
hintGCStats: "$1",
|
||||||
|
hintUser: "$1",
|
||||||
|
hintUserRaw: "$1"]
|
||||||
|
|
||||||
|
const
|
||||||
|
WarningsToStr* = ["CannotOpenFile", "OctalEscape",
|
||||||
|
"XIsNeverRead", "XmightNotBeenInit",
|
||||||
|
"Deprecated", "ConfigDeprecated",
|
||||||
|
"SmallLshouldNotBeUsed", "UnknownMagic",
|
||||||
|
"RedefinitionOfLabel", "UnknownSubstitutionX",
|
||||||
|
"LanguageXNotSupported", "FieldXNotSupported",
|
||||||
|
"CommentXIgnored",
|
||||||
|
"TypelessParam", "UseBase", "WriteToForeignHeap",
|
||||||
|
"UnsafeCode", "EachIdentIsTuple", "ShadowIdent",
|
||||||
|
"ProveInit", "ProveField", "ProveIndex", "GcUnsafe", "GcUnsafe2", "Uninit",
|
||||||
|
"GcMem", "Destructor", "LockLevel", "ResultShadowed",
|
||||||
|
"Spacing", "User"]
|
||||||
|
|
||||||
|
HintsToStr* = ["Success", "SuccessX", "LineTooLong",
|
||||||
|
"XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded",
|
||||||
|
"ExprAlwaysX", "QuitCalled", "Processing", "CodeBegin", "CodeEnd", "Conf",
|
||||||
|
"Path", "CondTrue", "Name", "Pattern", "Exec", "Link", "Dependency",
|
||||||
|
"Source", "Performance", "StackTrace", "GCStats",
|
||||||
|
"User", "UserRaw"]
|
||||||
|
|
||||||
|
const
|
||||||
|
fatalMin* = errUnknown
|
||||||
|
fatalMax* = errInternal
|
||||||
|
errMin* = errUnknown
|
||||||
|
errMax* = errUser
|
||||||
|
warnMin* = warnCannotOpenFile
|
||||||
|
warnMax* = pred(hintSuccess)
|
||||||
|
hintMin* = hintSuccess
|
||||||
|
hintMax* = high(TMsgKind)
|
||||||
|
|
||||||
|
static:
|
||||||
|
doAssert HintsToStr.len == ord(hintMax) - ord(hintMin) + 1
|
||||||
|
doAssert WarningsToStr.len == ord(warnMax) - ord(warnMin) + 1
|
||||||
|
|
||||||
|
type
|
||||||
|
TNoteKind* = range[warnMin..hintMax] # "notes" are warnings or hints
|
||||||
|
TNoteKinds* = set[TNoteKind]
|
||||||
|
|
||||||
|
const
|
||||||
|
NotesVerbosity*: array[0..3, TNoteKinds] = [
|
||||||
|
{low(TNoteKind)..high(TNoteKind)} - {warnShadowIdent, warnUninit,
|
||||||
|
warnProveField, warnProveIndex,
|
||||||
|
warnGcUnsafe,
|
||||||
|
hintSuccessX, hintPath, hintConf,
|
||||||
|
hintProcessing, hintPattern,
|
||||||
|
hintDependency,
|
||||||
|
hintExecuting, hintLinking,
|
||||||
|
hintCodeBegin, hintCodeEnd,
|
||||||
|
hintSource, hintStackTrace,
|
||||||
|
hintGCStats},
|
||||||
|
{low(TNoteKind)..high(TNoteKind)} - {warnShadowIdent, warnUninit,
|
||||||
|
warnProveField, warnProveIndex,
|
||||||
|
warnGcUnsafe,
|
||||||
|
hintPath,
|
||||||
|
hintDependency,
|
||||||
|
hintCodeBegin, hintCodeEnd,
|
||||||
|
hintSource, hintStackTrace,
|
||||||
|
hintGCStats},
|
||||||
|
{low(TNoteKind)..high(TNoteKind)} - {hintStackTrace, warnUninit},
|
||||||
|
{low(TNoteKind)..high(TNoteKind)}]
|
||||||
|
|
||||||
|
const
|
||||||
|
errXMustBeCompileTime* = "'$1' can only be used in compile-time context"
|
||||||
|
errArgsNeedRunOption* = "arguments can only be given if the '--run' option is selected"
|
||||||
|
|
||||||
|
type
|
||||||
|
TFileInfo* = object
|
||||||
|
fullPath*: string # This is a canonical full filesystem path
|
||||||
|
projPath*: string # This is relative to the project's root
|
||||||
|
shortName*: string # short name of the module
|
||||||
|
quotedName*: Rope # cached quoted short name for codegen
|
||||||
|
# purposes
|
||||||
|
quotedFullName*: Rope # cached quoted full name for codegen
|
||||||
|
# purposes
|
||||||
|
|
||||||
|
lines*: seq[Rope] # the source code of the module
|
||||||
|
# used for better error messages and
|
||||||
|
# embedding the original source in the
|
||||||
|
# generated code
|
||||||
|
dirtyfile*: string # the file that is actually read into memory
|
||||||
|
# and parsed; usually "" but is used
|
||||||
|
# for 'nimsuggest'
|
||||||
|
hash*: string # the checksum of the file
|
||||||
|
when defined(nimpretty):
|
||||||
|
fullContent*: string
|
||||||
|
FileIndex* = distinct int32
|
||||||
|
TLineInfo* = object # This is designed to be as small as possible,
|
||||||
|
# because it is used
|
||||||
|
# in syntax nodes. We save space here by using
|
||||||
|
# two int16 and an int32.
|
||||||
|
# On 64 bit and on 32 bit systems this is
|
||||||
|
# only 8 bytes.
|
||||||
|
line*: uint16
|
||||||
|
col*: int16
|
||||||
|
fileIndex*: FileIndex
|
||||||
|
when defined(nimpretty):
|
||||||
|
offsetA*, offsetB*: int
|
||||||
|
commentOffsetA*, commentOffsetB*: int
|
||||||
|
|
||||||
|
TErrorOutput* = enum
|
||||||
|
eStdOut
|
||||||
|
eStdErr
|
||||||
|
|
||||||
|
TErrorOutputs* = set[TErrorOutput]
|
||||||
|
|
||||||
|
ERecoverableError* = object of ValueError
|
||||||
|
ESuggestDone* = object of Exception
|
||||||
|
|
||||||
|
proc `==`*(a, b: FileIndex): bool {.borrow.}
|
||||||
|
|
||||||
|
const
|
||||||
|
InvalidFileIDX* = FileIndex(-1)
|
||||||
|
|
||||||
|
proc unknownLineInfo*(): TLineInfo =
|
||||||
|
result.line = uint16(0)
|
||||||
|
result.col = int16(-1)
|
||||||
|
result.fileIndex = InvalidFileIDX
|
||||||
|
|
||||||
|
type
|
||||||
|
Severity* {.pure.} = enum ## VS Code only supports these three
|
||||||
|
Hint, Warning, Error
|
||||||
|
|
||||||
|
const trackPosInvalidFileIdx* = FileIndex(-2) # special marker so that no suggestions
|
||||||
|
# are produced within comments and string literals
|
||||||
|
|
||||||
|
type
|
||||||
|
MsgConfig* = object
|
||||||
|
trackPos*: TLineInfo
|
||||||
|
trackPosAttached*: bool ## whether the tracking position was attached to some
|
||||||
|
## close token.
|
||||||
|
|
||||||
|
errorOutputs*: TErrorOutputs
|
||||||
|
msgContext*: seq[TLineInfo]
|
||||||
|
lastError*: TLineInfo
|
||||||
|
filenameToIndexTbl*: Table[string, FileIndex]
|
||||||
|
fileInfos*: seq[TFileInfo]
|
||||||
|
systemFileIdx*: FileIndex
|
||||||
|
|
||||||
|
|
||||||
|
proc initMsgConfig*(): MsgConfig =
|
||||||
|
result.msgContext = @[]
|
||||||
|
result.lastError = unknownLineInfo()
|
||||||
|
result.filenameToIndexTbl = initTable[string, FileIndex]()
|
||||||
|
result.fileInfos = @[]
|
||||||
|
result.errorOutputs = {eStdOut, eStdErr}
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
intsets, ast, astalgo, idents, semdata, types, msgs, options, rodread,
|
intsets, ast, astalgo, idents, semdata, types, msgs, options, rodread,
|
||||||
renderer, wordrecg, idgen, nimfix.prettybase, configuration, strutils
|
renderer, wordrecg, idgen, nimfix.prettybase, lineinfos, strutils
|
||||||
|
|
||||||
proc ensureNoMissingOrUnusedSymbols(c: PContext; scope: PScope)
|
proc ensureNoMissingOrUnusedSymbols(c: PContext; scope: PScope)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,8 @@
|
||||||
const
|
const
|
||||||
genPrefix* = ":tmp" # prefix for generated names
|
genPrefix* = ":tmp" # prefix for generated names
|
||||||
|
|
||||||
import ast, astalgo, types, idents, magicsys, msgs, options, modulegraphs
|
import ast, astalgo, types, idents, magicsys, msgs, options, modulegraphs,
|
||||||
|
lineinfos
|
||||||
from trees import getMagic
|
from trees import getMagic
|
||||||
|
|
||||||
proc newDeref*(n: PNode): PNode {.inline.} =
|
proc newDeref*(n: PNode): PNode {.inline.} =
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
ast, astalgo, hashes, msgs, platform, nversion, times, idents, rodread,
|
ast, astalgo, hashes, msgs, platform, nversion, times, idents, rodread,
|
||||||
modulegraphs
|
modulegraphs, lineinfos
|
||||||
|
|
||||||
export createMagic
|
export createMagic
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import
|
||||||
cgen, jsgen, json, nversion,
|
cgen, jsgen, json, nversion,
|
||||||
platform, nimconf, importer, passaux, depends, vm, vmdef, types, idgen,
|
platform, nimconf, importer, passaux, depends, vm, vmdef, types, idgen,
|
||||||
docgen2, service, parser, modules, ccgutils, sigmatch, ropes,
|
docgen2, service, parser, modules, ccgutils, sigmatch, ropes,
|
||||||
modulegraphs, tables, rod, configuration
|
modulegraphs, tables, rod, lineinfos
|
||||||
|
|
||||||
from magicsys import resetSysTypes
|
from magicsys import resetSysTypes
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
## - Its dependent module stays the same.
|
## - Its dependent module stays the same.
|
||||||
##
|
##
|
||||||
|
|
||||||
import ast, intsets, tables, options, rod, msgs, hashes, idents
|
import ast, intsets, tables, options, rod, lineinfos, hashes, idents
|
||||||
|
|
||||||
type
|
type
|
||||||
ModuleGraph* = ref object
|
ModuleGraph* = ref object
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
import ast, renderer, strutils, msgs, options, idents, os
|
import ast, renderer, strutils, msgs, options, idents, os, lineinfos
|
||||||
|
|
||||||
import nimblecmd
|
import nimblecmd
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
import
|
import
|
||||||
ast, astalgo, magicsys, std / sha1, rodread, msgs, cgendata, sigmatch, options,
|
ast, astalgo, magicsys, std / sha1, rodread, msgs, cgendata, sigmatch, options,
|
||||||
idents, os, lexer, idgen, passes, syntaxes, llstream, modulegraphs, rod,
|
idents, os, lexer, idgen, passes, syntaxes, llstream, modulegraphs, rod,
|
||||||
configuration
|
lineinfos
|
||||||
|
|
||||||
proc resetSystemArtifacts*(g: ModuleGraph) =
|
proc resetSystemArtifacts*(g: ModuleGraph) =
|
||||||
magicsys.resetSysTypes(g)
|
magicsys.resetSysTypes(g)
|
||||||
|
|
@ -118,8 +118,8 @@ proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex;
|
||||||
|
|
||||||
proc compileSystemModule*(graph: ModuleGraph; cache: IdentCache) =
|
proc compileSystemModule*(graph: ModuleGraph; cache: IdentCache) =
|
||||||
if graph.systemModule == nil:
|
if graph.systemModule == nil:
|
||||||
systemFileIdx = fileInfoIdx(graph.config, graph.config.libpath / "system.nim")
|
graph.config.m.systemFileIdx = fileInfoIdx(graph.config, graph.config.libpath / "system.nim")
|
||||||
discard graph.compileModule(systemFileIdx, cache, {sfSystemModule})
|
discard graph.compileModule(graph.config.m.systemFileIdx, cache, {sfSystemModule})
|
||||||
|
|
||||||
proc wantMainModule*(conf: ConfigRef) =
|
proc wantMainModule*(conf: ConfigRef) =
|
||||||
if conf.projectFull.len == 0:
|
if conf.projectFull.len == 0:
|
||||||
|
|
|
||||||
|
|
@ -9,83 +9,28 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
options, strutils, os, tables, ropes, platform, terminal, macros,
|
options, strutils, os, tables, ropes, platform, terminal, macros,
|
||||||
configuration
|
lineinfos
|
||||||
|
|
||||||
#type
|
proc toCChar*(c: char; result: var string) =
|
||||||
# MsgConfig* = ref object of RootObj
|
|
||||||
|
|
||||||
type
|
|
||||||
TFileInfo* = object
|
|
||||||
fullPath: string # This is a canonical full filesystem path
|
|
||||||
projPath*: string # This is relative to the project's root
|
|
||||||
shortName*: string # short name of the module
|
|
||||||
quotedName*: Rope # cached quoted short name for codegen
|
|
||||||
# purposes
|
|
||||||
quotedFullName*: Rope # cached quoted full name for codegen
|
|
||||||
# purposes
|
|
||||||
|
|
||||||
lines*: seq[Rope] # the source code of the module
|
|
||||||
# used for better error messages and
|
|
||||||
# embedding the original source in the
|
|
||||||
# generated code
|
|
||||||
dirtyfile: string # the file that is actually read into memory
|
|
||||||
# and parsed; usually 'nil' but is used
|
|
||||||
# for 'nimsuggest'
|
|
||||||
hash*: string # the checksum of the file
|
|
||||||
when defined(nimpretty):
|
|
||||||
fullContent*: string
|
|
||||||
FileIndex* = distinct int32
|
|
||||||
TLineInfo* = object # This is designed to be as small as possible,
|
|
||||||
# because it is used
|
|
||||||
# in syntax nodes. We save space here by using
|
|
||||||
# two int16 and an int32.
|
|
||||||
# On 64 bit and on 32 bit systems this is
|
|
||||||
# only 8 bytes.
|
|
||||||
line*: uint16
|
|
||||||
col*: int16
|
|
||||||
fileIndex*: FileIndex
|
|
||||||
when defined(nimpretty):
|
|
||||||
offsetA*, offsetB*: int
|
|
||||||
commentOffsetA*, commentOffsetB*: int
|
|
||||||
|
|
||||||
TErrorOutput* = enum
|
|
||||||
eStdOut
|
|
||||||
eStdErr
|
|
||||||
|
|
||||||
TErrorOutputs* = set[TErrorOutput]
|
|
||||||
|
|
||||||
ERecoverableError* = object of ValueError
|
|
||||||
ESuggestDone* = object of Exception
|
|
||||||
|
|
||||||
proc `==`*(a, b: FileIndex): bool {.borrow.}
|
|
||||||
|
|
||||||
|
|
||||||
const
|
|
||||||
InvalidFileIDX* = FileIndex(-1)
|
|
||||||
|
|
||||||
var
|
|
||||||
filenameToIndexTbl = initTable[string, FileIndex]()
|
|
||||||
fileInfos*: seq[TFileInfo] = @[]
|
|
||||||
systemFileIdx*: FileIndex
|
|
||||||
|
|
||||||
proc toCChar*(c: char): string =
|
|
||||||
case c
|
case c
|
||||||
of '\0'..'\x1F', '\x7F'..'\xFF': result = '\\' & toOctal(c)
|
of '\0'..'\x1F', '\x7F'..'\xFF':
|
||||||
of '\'', '\"', '\\', '?': result = '\\' & c
|
result.add '\\'
|
||||||
else: result = $(c)
|
result.add toOctal(c)
|
||||||
|
of '\'', '\"', '\\', '?':
|
||||||
|
result.add '\\'
|
||||||
|
result.add c
|
||||||
|
else:
|
||||||
|
result.add c
|
||||||
|
|
||||||
proc makeCString*(s: string): Rope =
|
proc makeCString*(s: string): Rope =
|
||||||
const
|
const MaxLineLength = 64
|
||||||
MaxLineLength = 64
|
|
||||||
result = nil
|
result = nil
|
||||||
var res = newStringOfCap(int(s.len.toFloat * 1.1) + 1)
|
var res = newStringOfCap(int(s.len.toFloat * 1.1) + 1)
|
||||||
add(res, "\"")
|
add(res, "\"")
|
||||||
for i in countup(0, len(s) - 1):
|
for i in countup(0, len(s) - 1):
|
||||||
if (i + 1) mod MaxLineLength == 0:
|
if (i + 1) mod MaxLineLength == 0:
|
||||||
add(res, '\"')
|
add(res, "\"\L\"")
|
||||||
add(res, '\L')
|
toCChar(s[i], res)
|
||||||
add(res, '\"')
|
|
||||||
add(res, toCChar(s[i]))
|
|
||||||
add(res, '\"')
|
add(res, '\"')
|
||||||
add(result, rope(res))
|
add(result, rope(res))
|
||||||
|
|
||||||
|
|
@ -110,8 +55,8 @@ proc newFileInfo(fullPath, projPath: string): TFileInfo =
|
||||||
result.fullContent = ""
|
result.fullContent = ""
|
||||||
|
|
||||||
when defined(nimpretty):
|
when defined(nimpretty):
|
||||||
proc fileSection*(fid: FileIndex; a, b: int): string =
|
proc fileSection*(conf: ConfigRef; fid: FileIndex; a, b: int): string =
|
||||||
substr(fileInfos[fid.int].fullContent, a, b)
|
substr(conf.m.fileInfos[fid.int].fullContent, a, b)
|
||||||
|
|
||||||
proc fileInfoKnown*(conf: ConfigRef; filename: string): bool =
|
proc fileInfoKnown*(conf: ConfigRef; filename: string): bool =
|
||||||
var
|
var
|
||||||
|
|
@ -120,7 +65,7 @@ proc fileInfoKnown*(conf: ConfigRef; filename: string): bool =
|
||||||
canon = canonicalizePath(conf, filename)
|
canon = canonicalizePath(conf, filename)
|
||||||
except:
|
except:
|
||||||
canon = filename
|
canon = filename
|
||||||
result = filenameToIndexTbl.hasKey(canon)
|
result = conf.m.filenameToIndexTbl.hasKey(canon)
|
||||||
|
|
||||||
proc fileInfoIdx*(conf: ConfigRef; filename: string; isKnownFile: var bool): FileIndex =
|
proc fileInfoIdx*(conf: ConfigRef; filename: string; isKnownFile: var bool): FileIndex =
|
||||||
var
|
var
|
||||||
|
|
@ -136,14 +81,14 @@ proc fileInfoIdx*(conf: ConfigRef; filename: string; isKnownFile: var bool): Fil
|
||||||
# This flag indicates that we are working with such a path here
|
# This flag indicates that we are working with such a path here
|
||||||
pseudoPath = true
|
pseudoPath = true
|
||||||
|
|
||||||
if filenameToIndexTbl.hasKey(canon):
|
if conf.m.filenameToIndexTbl.hasKey(canon):
|
||||||
result = filenameToIndexTbl[canon]
|
result = conf.m.filenameToIndexTbl[canon]
|
||||||
else:
|
else:
|
||||||
isKnownFile = false
|
isKnownFile = false
|
||||||
result = fileInfos.len.FileIndex
|
result = conf.m.fileInfos.len.FileIndex
|
||||||
fileInfos.add(newFileInfo(canon, if pseudoPath: filename
|
conf.m.fileInfos.add(newFileInfo(canon, if pseudoPath: filename
|
||||||
else: shortenDir(conf, canon)))
|
else: shortenDir(conf, canon)))
|
||||||
filenameToIndexTbl[canon] = result
|
conf.m.filenameToIndexTbl[canon] = result
|
||||||
|
|
||||||
proc fileInfoIdx*(conf: ConfigRef; filename: string): FileIndex =
|
proc fileInfoIdx*(conf: ConfigRef; filename: string): FileIndex =
|
||||||
var dummy: bool
|
var dummy: bool
|
||||||
|
|
@ -162,36 +107,19 @@ proc raiseRecoverableError*(msg: string) {.noinline, noreturn.} =
|
||||||
|
|
||||||
proc sourceLine*(conf: ConfigRef; i: TLineInfo): Rope
|
proc sourceLine*(conf: ConfigRef; i: TLineInfo): Rope
|
||||||
|
|
||||||
proc unknownLineInfo*(): TLineInfo =
|
|
||||||
result.line = uint16(0)
|
|
||||||
result.col = int16(-1)
|
|
||||||
result.fileIndex = InvalidFileIDX
|
|
||||||
|
|
||||||
type
|
|
||||||
Severity* {.pure.} = enum ## VS Code only supports these three
|
|
||||||
Hint, Warning, Error
|
|
||||||
|
|
||||||
var
|
|
||||||
msgContext: seq[TLineInfo] = @[]
|
|
||||||
lastError = unknownLineInfo()
|
|
||||||
|
|
||||||
errorOutputs* = {eStdOut, eStdErr}
|
|
||||||
writelnHook*: proc (output: string) {.closure.}
|
|
||||||
structuredErrorHook*: proc (config: ConfigRef; info: TLineInfo; msg: string; severity: Severity) {.closure.}
|
|
||||||
|
|
||||||
proc concat(strings: openarray[string]): string =
|
proc concat(strings: openarray[string]): string =
|
||||||
var totalLen = 0
|
var totalLen = 0
|
||||||
for s in strings: totalLen += s.len
|
for s in strings: totalLen += s.len
|
||||||
result = newStringOfCap totalLen
|
result = newStringOfCap totalLen
|
||||||
for s in strings: result.add s
|
for s in strings: result.add s
|
||||||
|
|
||||||
proc suggestWriteln*(s: string) =
|
proc suggestWriteln*(conf: ConfigRef; s: string) =
|
||||||
if eStdOut in errorOutputs:
|
if eStdOut in conf.m.errorOutputs:
|
||||||
if isNil(writelnHook):
|
if isNil(conf.writelnHook):
|
||||||
writeLine(stdout, s)
|
writeLine(stdout, s)
|
||||||
flushFile(stdout)
|
flushFile(stdout)
|
||||||
else:
|
else:
|
||||||
writelnHook(s)
|
conf.writelnHook(s)
|
||||||
|
|
||||||
proc msgQuit*(x: int8) = quit x
|
proc msgQuit*(x: int8) = quit x
|
||||||
proc msgQuit*(x: string) = quit x
|
proc msgQuit*(x: string) = quit x
|
||||||
|
|
@ -212,47 +140,47 @@ const
|
||||||
HintTitle = "Hint: "
|
HintTitle = "Hint: "
|
||||||
HintColor = fgGreen
|
HintColor = fgGreen
|
||||||
|
|
||||||
proc getInfoContextLen*(): int = return msgContext.len
|
proc getInfoContextLen*(conf: ConfigRef): int = return conf.m.msgContext.len
|
||||||
proc setInfoContextLen*(L: int) = setLen(msgContext, L)
|
proc setInfoContextLen*(conf: ConfigRef; L: int) = setLen(conf.m.msgContext, L)
|
||||||
|
|
||||||
proc pushInfoContext*(info: TLineInfo) =
|
proc pushInfoContext*(conf: ConfigRef; info: TLineInfo) =
|
||||||
msgContext.add(info)
|
conf.m.msgContext.add(info)
|
||||||
|
|
||||||
proc popInfoContext*() =
|
proc popInfoContext*(conf: ConfigRef) =
|
||||||
setLen(msgContext, len(msgContext) - 1)
|
setLen(conf.m.msgContext, len(conf.m.msgContext) - 1)
|
||||||
|
|
||||||
proc getInfoContext*(index: int): TLineInfo =
|
proc getInfoContext*(conf: ConfigRef; index: int): TLineInfo =
|
||||||
let L = msgContext.len
|
let L = conf.m.msgContext.len
|
||||||
let i = if index < 0: L + index else: index
|
let i = if index < 0: L + index else: index
|
||||||
if i >=% L: result = unknownLineInfo()
|
if i >=% L: result = unknownLineInfo()
|
||||||
else: result = msgContext[i]
|
else: result = conf.m.msgContext[i]
|
||||||
|
|
||||||
template toFilename*(conf: ConfigRef; fileIdx: FileIndex): string =
|
template toFilename*(conf: ConfigRef; fileIdx: FileIndex): string =
|
||||||
(if fileIdx.int32 < 0: "???" else: fileInfos[fileIdx.int32].projPath)
|
(if fileIdx.int32 < 0: "???" else: conf.m.fileInfos[fileIdx.int32].projPath)
|
||||||
|
|
||||||
proc toFullPath*(conf: ConfigRef; fileIdx: FileIndex): string =
|
proc toFullPath*(conf: ConfigRef; fileIdx: FileIndex): string =
|
||||||
if fileIdx.int32 < 0: result = "???"
|
if fileIdx.int32 < 0: result = "???"
|
||||||
else: result = fileInfos[fileIdx.int32].fullPath
|
else: result = conf.m.fileInfos[fileIdx.int32].fullPath
|
||||||
|
|
||||||
proc setDirtyFile*(conf: ConfigRef; fileIdx: FileIndex; filename: string) =
|
proc setDirtyFile*(conf: ConfigRef; fileIdx: FileIndex; filename: string) =
|
||||||
assert fileIdx.int32 >= 0
|
assert fileIdx.int32 >= 0
|
||||||
fileInfos[fileIdx.int32].dirtyFile = filename
|
conf.m.fileInfos[fileIdx.int32].dirtyFile = filename
|
||||||
|
|
||||||
proc setHash*(conf: ConfigRef; fileIdx: FileIndex; hash: string) =
|
proc setHash*(conf: ConfigRef; fileIdx: FileIndex; hash: string) =
|
||||||
assert fileIdx.int32 >= 0
|
assert fileIdx.int32 >= 0
|
||||||
shallowCopy(fileInfos[fileIdx.int32].hash, hash)
|
shallowCopy(conf.m.fileInfos[fileIdx.int32].hash, hash)
|
||||||
|
|
||||||
proc getHash*(conf: ConfigRef; fileIdx: FileIndex): string =
|
proc getHash*(conf: ConfigRef; fileIdx: FileIndex): string =
|
||||||
assert fileIdx.int32 >= 0
|
assert fileIdx.int32 >= 0
|
||||||
shallowCopy(result, fileInfos[fileIdx.int32].hash)
|
shallowCopy(result, conf.m.fileInfos[fileIdx.int32].hash)
|
||||||
|
|
||||||
proc toFullPathConsiderDirty*(conf: ConfigRef; fileIdx: FileIndex): string =
|
proc toFullPathConsiderDirty*(conf: ConfigRef; fileIdx: FileIndex): string =
|
||||||
if fileIdx.int32 < 0:
|
if fileIdx.int32 < 0:
|
||||||
result = "???"
|
result = "???"
|
||||||
elif not fileInfos[fileIdx.int32].dirtyFile.isNil:
|
elif not conf.m.fileInfos[fileIdx.int32].dirtyFile.isNil:
|
||||||
result = fileInfos[fileIdx.int32].dirtyFile
|
result = conf.m.fileInfos[fileIdx.int32].dirtyFile
|
||||||
else:
|
else:
|
||||||
result = fileInfos[fileIdx.int32].fullPath
|
result = conf.m.fileInfos[fileIdx.int32].fullPath
|
||||||
|
|
||||||
template toFilename*(conf: ConfigRef; info: TLineInfo): string =
|
template toFilename*(conf: ConfigRef; info: TLineInfo): string =
|
||||||
toFilename(conf, info.fileIndex)
|
toFilename(conf, info.fileIndex)
|
||||||
|
|
@ -264,9 +192,9 @@ proc toMsgFilename*(conf: ConfigRef; info: TLineInfo): string =
|
||||||
if info.fileIndex.int32 < 0:
|
if info.fileIndex.int32 < 0:
|
||||||
result = "???"
|
result = "???"
|
||||||
elif optListFullPaths in conf.globalOptions:
|
elif optListFullPaths in conf.globalOptions:
|
||||||
result = fileInfos[info.fileIndex.int32].fullPath
|
result = conf.m.fileInfos[info.fileIndex.int32].fullPath
|
||||||
else:
|
else:
|
||||||
result = fileInfos[info.fileIndex.int32].projPath
|
result = conf.m.fileInfos[info.fileIndex.int32].projPath
|
||||||
|
|
||||||
proc toLinenumber*(info: TLineInfo): int {.inline.} =
|
proc toLinenumber*(info: TLineInfo): int {.inline.} =
|
||||||
result = int info.line
|
result = int info.line
|
||||||
|
|
@ -288,12 +216,6 @@ proc `??`* (conf: ConfigRef; info: TLineInfo, filename: string): bool =
|
||||||
# only for debugging purposes
|
# only for debugging purposes
|
||||||
result = filename in toFilename(conf, info)
|
result = filename in toFilename(conf, info)
|
||||||
|
|
||||||
const trackPosInvalidFileIdx* = FileIndex(-2) # special marker so that no suggestions
|
|
||||||
# are produced within comments and string literals
|
|
||||||
var gTrackPos*: TLineInfo
|
|
||||||
var gTrackPosAttached*: bool ## whether the tracking position was attached to some
|
|
||||||
## close token.
|
|
||||||
|
|
||||||
type
|
type
|
||||||
MsgFlag* = enum ## flags altering msgWriteln behavior
|
MsgFlag* = enum ## flags altering msgWriteln behavior
|
||||||
msgStdout, ## force writing to stdout, even stderr is default
|
msgStdout, ## force writing to stdout, even stderr is default
|
||||||
|
|
@ -310,14 +232,14 @@ proc msgWriteln*(conf: ConfigRef; s: string, flags: MsgFlags = {}) =
|
||||||
## support.
|
## support.
|
||||||
#if conf.cmd == cmdIdeTools and optCDebug notin gGlobalOptions: return
|
#if conf.cmd == cmdIdeTools and optCDebug notin gGlobalOptions: return
|
||||||
|
|
||||||
if not isNil(writelnHook) and msgSkipHook notin flags:
|
if not isNil(conf.writelnHook) and msgSkipHook notin flags:
|
||||||
writelnHook(s)
|
conf.writelnHook(s)
|
||||||
elif optStdout in conf.globalOptions or msgStdout in flags:
|
elif optStdout in conf.globalOptions or msgStdout in flags:
|
||||||
if eStdOut in errorOutputs:
|
if eStdOut in conf.m.errorOutputs:
|
||||||
writeLine(stdout, s)
|
writeLine(stdout, s)
|
||||||
flushFile(stdout)
|
flushFile(stdout)
|
||||||
else:
|
else:
|
||||||
if eStdErr in errorOutputs:
|
if eStdErr in conf.m.errorOutputs:
|
||||||
writeLine(stderr, s)
|
writeLine(stderr, s)
|
||||||
# On Windows stderr is fully-buffered when piped, regardless of C std.
|
# On Windows stderr is fully-buffered when piped, regardless of C std.
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
|
|
@ -348,17 +270,17 @@ macro callStyledWriteLineStderr(args: varargs[typed]): untyped =
|
||||||
result.add(arg)
|
result.add(arg)
|
||||||
|
|
||||||
template callWritelnHook(args: varargs[string, `$`]) =
|
template callWritelnHook(args: varargs[string, `$`]) =
|
||||||
writelnHook concat(args)
|
conf.writelnHook concat(args)
|
||||||
|
|
||||||
template styledMsgWriteln*(args: varargs[typed]) =
|
template styledMsgWriteln*(args: varargs[typed]) =
|
||||||
if not isNil(writelnHook):
|
if not isNil(conf.writelnHook):
|
||||||
callIgnoringStyle(callWritelnHook, nil, args)
|
callIgnoringStyle(callWritelnHook, nil, args)
|
||||||
elif optStdout in conf.globalOptions:
|
elif optStdout in conf.globalOptions:
|
||||||
if eStdOut in errorOutputs:
|
if eStdOut in conf.m.errorOutputs:
|
||||||
callIgnoringStyle(writeLine, stdout, args)
|
callIgnoringStyle(writeLine, stdout, args)
|
||||||
flushFile(stdout)
|
flushFile(stdout)
|
||||||
else:
|
else:
|
||||||
if eStdErr in errorOutputs:
|
if eStdErr in conf.m.errorOutputs:
|
||||||
if optUseColors in conf.globalOptions:
|
if optUseColors in conf.globalOptions:
|
||||||
callStyledWriteLineStderr(args)
|
callStyledWriteLineStderr(args)
|
||||||
else:
|
else:
|
||||||
|
|
@ -389,7 +311,7 @@ proc log*(s: string) {.procvar.} =
|
||||||
|
|
||||||
proc quit(conf: ConfigRef; msg: TMsgKind) =
|
proc quit(conf: ConfigRef; msg: TMsgKind) =
|
||||||
if defined(debug) or msg == errInternal or hintStackTrace in conf.notes:
|
if defined(debug) or msg == errInternal or hintStackTrace in conf.notes:
|
||||||
if stackTraceAvailable() and isNil(writelnHook):
|
if stackTraceAvailable() and isNil(conf.writelnHook):
|
||||||
writeStackTrace()
|
writeStackTrace()
|
||||||
else:
|
else:
|
||||||
styledMsgWriteln(fgRed, "No stack traceback available\n" &
|
styledMsgWriteln(fgRed, "No stack traceback available\n" &
|
||||||
|
|
@ -420,19 +342,19 @@ proc exactEquals*(a, b: TLineInfo): bool =
|
||||||
proc writeContext(conf: ConfigRef; lastinfo: TLineInfo) =
|
proc writeContext(conf: ConfigRef; lastinfo: TLineInfo) =
|
||||||
const instantiationFrom = "template/generic instantiation from here"
|
const instantiationFrom = "template/generic instantiation from here"
|
||||||
var info = lastinfo
|
var info = lastinfo
|
||||||
for i in countup(0, len(msgContext) - 1):
|
for i in 0 ..< len(conf.m.msgContext):
|
||||||
if msgContext[i] != lastinfo and msgContext[i] != info:
|
if conf.m.msgContext[i] != lastinfo and conf.m.msgContext[i] != info:
|
||||||
if structuredErrorHook != nil:
|
if conf.structuredErrorHook != nil:
|
||||||
structuredErrorHook(conf, msgContext[i], instantiationFrom,
|
conf.structuredErrorHook(conf, conf.m.msgContext[i], instantiationFrom,
|
||||||
Severity.Error)
|
Severity.Error)
|
||||||
else:
|
else:
|
||||||
styledMsgWriteln(styleBright,
|
styledMsgWriteln(styleBright,
|
||||||
PosFormat % [toMsgFilename(conf, msgContext[i]),
|
PosFormat % [toMsgFilename(conf, conf.m.msgContext[i]),
|
||||||
coordToStr(msgContext[i].line.int),
|
coordToStr(conf.m.msgContext[i].line.int),
|
||||||
coordToStr(msgContext[i].col+1)],
|
coordToStr(conf.m.msgContext[i].col+1)],
|
||||||
resetStyle,
|
resetStyle,
|
||||||
instantiationFrom)
|
instantiationFrom)
|
||||||
info = msgContext[i]
|
info = conf.m.msgContext[i]
|
||||||
|
|
||||||
proc ignoreMsgBecauseOfIdeTools(conf: ConfigRef; msg: TMsgKind): bool =
|
proc ignoreMsgBecauseOfIdeTools(conf: ConfigRef; msg: TMsgKind): bool =
|
||||||
msg >= errGenerated and conf.cmd == cmdIdeTools and optIdeDebug notin conf.globalOptions
|
msg >= errGenerated and conf.cmd == cmdIdeTools and optIdeDebug notin conf.globalOptions
|
||||||
|
|
@ -468,8 +390,9 @@ proc rawMessage*(conf: ConfigRef; msg: TMsgKind, args: openArray[string]) =
|
||||||
inc(conf.hintCounter)
|
inc(conf.hintCounter)
|
||||||
let s = msgKindToString(msg) % args
|
let s = msgKindToString(msg) % args
|
||||||
|
|
||||||
if structuredErrorHook != nil:
|
if conf.structuredErrorHook != nil:
|
||||||
structuredErrorHook(conf, unknownLineInfo(), s & (if kind != nil: KindFormat % kind else: ""), sev)
|
conf.structuredErrorHook(conf, unknownLineInfo(),
|
||||||
|
s & (if kind != nil: KindFormat % kind else: ""), sev)
|
||||||
|
|
||||||
if not ignoreMsgBecauseOfIdeTools(conf, msg):
|
if not ignoreMsgBecauseOfIdeTools(conf, msg):
|
||||||
if kind != nil:
|
if kind != nil:
|
||||||
|
|
@ -518,7 +441,7 @@ proc liMessage(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg: string,
|
||||||
# we try to filter error messages so that not two error message
|
# we try to filter error messages so that not two error message
|
||||||
# in the same file and line are produced:
|
# in the same file and line are produced:
|
||||||
#ignoreMsg = lastError == info and eh != doAbort
|
#ignoreMsg = lastError == info and eh != doAbort
|
||||||
lastError = info
|
conf.m.lastError = info
|
||||||
of warnMin..warnMax:
|
of warnMin..warnMax:
|
||||||
sev = Severity.Warning
|
sev = Severity.Warning
|
||||||
ignoreMsg = optWarns notin conf.options or msg notin conf.notes
|
ignoreMsg = optWarns notin conf.options or msg notin conf.notes
|
||||||
|
|
@ -542,8 +465,8 @@ proc liMessage(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg: string,
|
||||||
let s = getMessageStr(msg, arg)
|
let s = getMessageStr(msg, arg)
|
||||||
|
|
||||||
if not ignoreMsg:
|
if not ignoreMsg:
|
||||||
if structuredErrorHook != nil:
|
if conf.structuredErrorHook != nil:
|
||||||
structuredErrorHook(conf, info, s & (if kind != nil: KindFormat % kind else: ""), sev)
|
conf.structuredErrorHook(conf, info, s & (if kind != nil: KindFormat % kind else: ""), sev)
|
||||||
if not ignoreMsgBecauseOfIdeTools(conf, msg):
|
if not ignoreMsgBecauseOfIdeTools(conf, msg):
|
||||||
if kind != nil:
|
if kind != nil:
|
||||||
styledMsgWriteln(styleBright, x, resetStyle, color, title, resetStyle, s,
|
styledMsgWriteln(styleBright, x, resetStyle, color, title, resetStyle, s,
|
||||||
|
|
@ -557,7 +480,7 @@ proc liMessage(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg: string,
|
||||||
proc fatal*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg = "") =
|
proc fatal*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg = "") =
|
||||||
# this fixes bug #7080 so that it is at least obvious 'fatal'
|
# this fixes bug #7080 so that it is at least obvious 'fatal'
|
||||||
# was executed.
|
# was executed.
|
||||||
errorOutputs = {eStdOut, eStdErr}
|
conf.m.errorOutputs = {eStdOut, eStdErr}
|
||||||
liMessage(conf, info, msg, arg, doAbort)
|
liMessage(conf, info, msg, arg, doAbort)
|
||||||
|
|
||||||
proc globalError*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg = "") =
|
proc globalError*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg = "") =
|
||||||
|
|
@ -579,12 +502,12 @@ proc message*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg = "") =
|
||||||
liMessage(conf, info, msg, arg, doNothing)
|
liMessage(conf, info, msg, arg, doNothing)
|
||||||
|
|
||||||
proc internalError*(conf: ConfigRef; info: TLineInfo, errMsg: string) =
|
proc internalError*(conf: ConfigRef; info: TLineInfo, errMsg: string) =
|
||||||
if conf.cmd == cmdIdeTools and structuredErrorHook.isNil: return
|
if conf.cmd == cmdIdeTools and conf.structuredErrorHook.isNil: return
|
||||||
writeContext(conf, info)
|
writeContext(conf, info)
|
||||||
liMessage(conf, info, errInternal, errMsg, doAbort)
|
liMessage(conf, info, errInternal, errMsg, doAbort)
|
||||||
|
|
||||||
proc internalError*(conf: ConfigRef; errMsg: string) =
|
proc internalError*(conf: ConfigRef; errMsg: string) =
|
||||||
if conf.cmd == cmdIdeTools and structuredErrorHook.isNil: return
|
if conf.cmd == cmdIdeTools and conf.structuredErrorHook.isNil: return
|
||||||
writeContext(conf, unknownLineInfo())
|
writeContext(conf, unknownLineInfo())
|
||||||
rawMessage(conf, errInternal, errMsg)
|
rawMessage(conf, errInternal, errMsg)
|
||||||
|
|
||||||
|
|
@ -596,36 +519,36 @@ template internalAssert*(conf: ConfigRef, e: bool) =
|
||||||
if not e: internalError(conf, $instantiationInfo())
|
if not e: internalError(conf, $instantiationInfo())
|
||||||
|
|
||||||
proc addSourceLine*(conf: ConfigRef; fileIdx: FileIndex, line: string) =
|
proc addSourceLine*(conf: ConfigRef; fileIdx: FileIndex, line: string) =
|
||||||
fileInfos[fileIdx.int32].lines.add line.rope
|
conf.m.fileInfos[fileIdx.int32].lines.add line.rope
|
||||||
|
|
||||||
proc sourceLine*(conf: ConfigRef; i: TLineInfo): Rope =
|
proc sourceLine*(conf: ConfigRef; i: TLineInfo): Rope =
|
||||||
if i.fileIndex.int32 < 0: return nil
|
if i.fileIndex.int32 < 0: return nil
|
||||||
|
|
||||||
if not optPreserveOrigSource(conf) and fileInfos[i.fileIndex.int32].lines.len == 0:
|
if not optPreserveOrigSource(conf) and conf.m.fileInfos[i.fileIndex.int32].lines.len == 0:
|
||||||
try:
|
try:
|
||||||
for line in lines(toFullPath(conf, i)):
|
for line in lines(toFullPath(conf, i)):
|
||||||
addSourceLine conf, i.fileIndex, line.string
|
addSourceLine conf, i.fileIndex, line.string
|
||||||
except IOError:
|
except IOError:
|
||||||
discard
|
discard
|
||||||
assert i.fileIndex.int32 < fileInfos.len
|
assert i.fileIndex.int32 < conf.m.fileInfos.len
|
||||||
# can happen if the error points to EOF:
|
# can happen if the error points to EOF:
|
||||||
if i.line.int > fileInfos[i.fileIndex.int32].lines.len: return nil
|
if i.line.int > conf.m.fileInfos[i.fileIndex.int32].lines.len: return nil
|
||||||
|
|
||||||
result = fileInfos[i.fileIndex.int32].lines[i.line.int-1]
|
result = conf.m.fileInfos[i.fileIndex.int32].lines[i.line.int-1]
|
||||||
|
|
||||||
proc quotedFilename*(conf: ConfigRef; i: TLineInfo): Rope =
|
proc quotedFilename*(conf: ConfigRef; i: TLineInfo): Rope =
|
||||||
assert i.fileIndex.int32 >= 0
|
assert i.fileIndex.int32 >= 0
|
||||||
if optExcessiveStackTrace in conf.globalOptions:
|
if optExcessiveStackTrace in conf.globalOptions:
|
||||||
result = fileInfos[i.fileIndex.int32].quotedFullName
|
result = conf.m.fileInfos[i.fileIndex.int32].quotedFullName
|
||||||
else:
|
else:
|
||||||
result = fileInfos[i.fileIndex.int32].quotedName
|
result = conf.m.fileInfos[i.fileIndex.int32].quotedName
|
||||||
|
|
||||||
proc listWarnings*(conf: ConfigRef) =
|
proc listWarnings*(conf: ConfigRef) =
|
||||||
msgWriteln(conf, "Warnings:")
|
msgWriteln(conf, "Warnings:")
|
||||||
for warn in warnMin..warnMax:
|
for warn in warnMin..warnMax:
|
||||||
msgWriteln(conf, " [$1] $2" % [
|
msgWriteln(conf, " [$1] $2" % [
|
||||||
if warn in conf.notes: "x" else: " ",
|
if warn in conf.notes: "x" else: " ",
|
||||||
configuration.WarningsToStr[ord(warn) - ord(warnMin)]
|
lineinfos.WarningsToStr[ord(warn) - ord(warnMin)]
|
||||||
])
|
])
|
||||||
|
|
||||||
proc listHints*(conf: ConfigRef) =
|
proc listHints*(conf: ConfigRef) =
|
||||||
|
|
@ -633,5 +556,5 @@ proc listHints*(conf: ConfigRef) =
|
||||||
for hint in hintMin..hintMax:
|
for hint in hintMin..hintMax:
|
||||||
msgWriteln(conf, " [$1] $2" % [
|
msgWriteln(conf, " [$1] $2" % [
|
||||||
if hint in conf.notes: "x" else: " ",
|
if hint in conf.notes: "x" else: " ",
|
||||||
configuration.HintsToStr[ord(hint) - ord(hintMin)]
|
lineinfos.HintsToStr[ord(hint) - ord(hintMin)]
|
||||||
])
|
])
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ when defined(i386) and defined(windows) and defined(vcc):
|
||||||
import
|
import
|
||||||
commands, lexer, condsyms, options, msgs, nversion, nimconf, ropes,
|
commands, lexer, condsyms, options, msgs, nversion, nimconf, ropes,
|
||||||
extccomp, strutils, os, osproc, platform, main, parseopt, service,
|
extccomp, strutils, os, osproc, platform, main, parseopt, service,
|
||||||
nodejs, scriptconfig, idents, modulegraphs, configuration
|
nodejs, scriptconfig, idents, modulegraphs, lineinfos
|
||||||
|
|
||||||
when hasTinyCBackend:
|
when hasTinyCBackend:
|
||||||
import tccgen
|
import tccgen
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
## Implements some helper procs for Nimble (Nim's package manager) support.
|
## Implements some helper procs for Nimble (Nim's package manager) support.
|
||||||
|
|
||||||
import parseutils, strutils, strtabs, os, options, msgs, sequtils,
|
import parseutils, strutils, strtabs, os, options, msgs, sequtils,
|
||||||
configuration
|
lineinfos
|
||||||
|
|
||||||
proc addPath*(conf: ConfigRef; path: string, info: TLineInfo) =
|
proc addPath*(conf: ConfigRef; path: string, info: TLineInfo) =
|
||||||
if not conf.searchPaths.contains(path):
|
if not conf.searchPaths.contains(path):
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
llstream, nversion, commands, os, strutils, msgs, platform, condsyms, lexer,
|
llstream, nversion, commands, os, strutils, msgs, platform, condsyms, lexer,
|
||||||
options, idents, wordrecg, strtabs, configuration
|
options, idents, wordrecg, strtabs, lineinfos
|
||||||
|
|
||||||
# ---------------- configuration file parser -----------------------------
|
# ---------------- configuration file parser -----------------------------
|
||||||
# we use Nim's scanner here to save space and work
|
# we use Nim's scanner here to save space and work
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import
|
||||||
strutils, os, intsets, strtabs
|
strutils, os, intsets, strtabs
|
||||||
|
|
||||||
import ".." / [options, ast, astalgo, msgs, semdata, ropes, idents,
|
import ".." / [options, ast, astalgo, msgs, semdata, ropes, idents,
|
||||||
configuration]
|
lineinfos]
|
||||||
import prettybase
|
import prettybase
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import strutils, lexbase, streams
|
import strutils, lexbase, streams
|
||||||
import ".." / [ast, msgs, idents, options]
|
import ".." / [ast, msgs, lineinfos, idents, options]
|
||||||
from os import splitFile
|
from os import splitFile
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
# this unit handles Nim sets; it implements symbolic sets
|
# this unit handles Nim sets; it implements symbolic sets
|
||||||
|
|
||||||
import
|
import
|
||||||
ast, astalgo, trees, nversion, msgs, platform, bitsets, types, renderer,
|
ast, astalgo, trees, nversion, lineinfos, platform, bitsets, types, renderer,
|
||||||
options
|
options
|
||||||
|
|
||||||
proc inSet*(s: PNode, elem: PNode): bool =
|
proc inSet*(s: PNode, elem: PNode): bool =
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,6 @@ const
|
||||||
VersionAsString* = system.NimVersion
|
VersionAsString* = system.NimVersion
|
||||||
RodFileVersion* = "1223" # modify this if the rod-format changes!
|
RodFileVersion* = "1223" # modify this if the rod-format changes!
|
||||||
|
|
||||||
NimCompilerApiVersion* = 1 ## Check for the existance of this before accessing it
|
NimCompilerApiVersion* = 2 ## Check for the existance of this before accessing it
|
||||||
## as older versions of the compiler API do not
|
## as older versions of the compiler API do not
|
||||||
## declare this.
|
## declare this.
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,8 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import
|
import
|
||||||
os, strutils, strtabs, osproc, sets, configuration, platform
|
os, strutils, strtabs, osproc, sets, lineinfos, platform,
|
||||||
|
prefixmatches
|
||||||
|
|
||||||
from terminal import isatty
|
from terminal import isatty
|
||||||
|
|
||||||
|
|
@ -135,11 +136,33 @@ type
|
||||||
flags*: set[CFileFlag]
|
flags*: set[CFileFlag]
|
||||||
CfileList* = seq[Cfile]
|
CfileList* = seq[Cfile]
|
||||||
|
|
||||||
|
Suggest* = ref object
|
||||||
|
section*: IdeCmd
|
||||||
|
qualifiedPath*: seq[string]
|
||||||
|
name*: ptr string # not used beyond sorting purposes; name is also
|
||||||
|
# part of 'qualifiedPath'
|
||||||
|
filePath*: string
|
||||||
|
line*: int # Starts at 1
|
||||||
|
column*: int # Starts at 0
|
||||||
|
doc*: string # Not escaped (yet)
|
||||||
|
forth*: string # type
|
||||||
|
quality*: range[0..100] # matching quality
|
||||||
|
isGlobal*: bool # is a global variable
|
||||||
|
contextFits*: bool # type/non-type context matches
|
||||||
|
prefix*: PrefixMatch
|
||||||
|
symkind*: byte
|
||||||
|
scope*, localUsages*, globalUsages*: int # more usages is better
|
||||||
|
tokenLen*: int
|
||||||
|
version*: int
|
||||||
|
Suggestions* = seq[Suggest]
|
||||||
|
|
||||||
ConfigRef* = ref object ## eventually all global configuration should be moved here
|
ConfigRef* = ref object ## eventually all global configuration should be moved here
|
||||||
target*: Target
|
target*: Target
|
||||||
linesCompiled*: int # all lines that have been compiled
|
linesCompiled*: int # all lines that have been compiled
|
||||||
options*: TOptions
|
options*: TOptions
|
||||||
globalOptions*: TGlobalOptions
|
globalOptions*: TGlobalOptions
|
||||||
|
m*: MsgConfig
|
||||||
|
evalTemplateCounter*: int
|
||||||
exitcode*: int8
|
exitcode*: int8
|
||||||
cmd*: TCommands # the command
|
cmd*: TCommands # the command
|
||||||
selectedGC*: TGCMode # the selected GC
|
selectedGC*: TGCMode # the selected GC
|
||||||
|
|
@ -202,6 +225,13 @@ type
|
||||||
compileOptions*: string
|
compileOptions*: string
|
||||||
ccompilerpath*: string
|
ccompilerpath*: string
|
||||||
toCompile*: CfileList
|
toCompile*: CfileList
|
||||||
|
suggestionResultHook*: proc (result: Suggest) {.closure.}
|
||||||
|
suggestVersion*: int
|
||||||
|
suggestMaxResults*: int
|
||||||
|
lastLineInfo*: TLineInfo
|
||||||
|
writelnHook*: proc (output: string) {.closure.}
|
||||||
|
structuredErrorHook*: proc (config: ConfigRef; info: TLineInfo; msg: string;
|
||||||
|
severity: Severity) {.closure.}
|
||||||
|
|
||||||
const oldExperimentalFeatures* = {implicitDeref, dotOperators, callOperator, parallel}
|
const oldExperimentalFeatures* = {implicitDeref, dotOperators, callOperator, parallel}
|
||||||
|
|
||||||
|
|
@ -229,6 +259,7 @@ proc newConfigRef*(): ConfigRef =
|
||||||
verbosity: 1,
|
verbosity: 1,
|
||||||
options: DefaultOptions,
|
options: DefaultOptions,
|
||||||
globalOptions: DefaultGlobalOptions,
|
globalOptions: DefaultGlobalOptions,
|
||||||
|
m: initMsgConfig(),
|
||||||
evalExpr: "",
|
evalExpr: "",
|
||||||
cppDefines: initSet[string](),
|
cppDefines: initSet[string](),
|
||||||
headerFile: "", features: {}, foreignPackageNotes: {hintProcessing, warnUnknownMagic,
|
headerFile: "", features: {}, foreignPackageNotes: {hintProcessing, warnUnknownMagic,
|
||||||
|
|
@ -264,7 +295,8 @@ proc newConfigRef*(): ConfigRef =
|
||||||
compileOptions: "",
|
compileOptions: "",
|
||||||
ccompilerpath: "",
|
ccompilerpath: "",
|
||||||
toCompile: @[],
|
toCompile: @[],
|
||||||
arguments: ""
|
arguments: "",
|
||||||
|
suggestMaxResults: 10_000
|
||||||
)
|
)
|
||||||
setTargetFromSystem(result.target)
|
setTargetFromSystem(result.target)
|
||||||
# enable colors by default on terminals
|
# enable colors by default on terminals
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ when isMainModule:
|
||||||
outp.close
|
outp.close
|
||||||
|
|
||||||
import
|
import
|
||||||
llstream, lexer, idents, strutils, ast, astalgo, msgs, options, configuration
|
llstream, lexer, idents, strutils, ast, astalgo, msgs, options, lineinfos
|
||||||
|
|
||||||
type
|
type
|
||||||
TParser* = object # A TParser object represents a file that
|
TParser* = object # A TParser object represents a file that
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
## implements some little helper passes
|
## implements some little helper passes
|
||||||
|
|
||||||
import
|
import
|
||||||
strutils, ast, astalgo, passes, idents, msgs, options, idgen, configuration
|
strutils, ast, astalgo, passes, idents, msgs, options, idgen, lineinfos
|
||||||
|
|
||||||
from modulegraphs import ModuleGraph
|
from modulegraphs import ModuleGraph
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import
|
||||||
strutils, options, ast, astalgo, llstream, msgs, platform, os,
|
strutils, options, ast, astalgo, llstream, msgs, platform, os,
|
||||||
condsyms, idents, renderer, types, extccomp, math, magicsys, nversion,
|
condsyms, idents, renderer, types, extccomp, math, magicsys, nversion,
|
||||||
nimsets, syntaxes, times, rodread, idgen, modulegraphs, reorder, rod,
|
nimsets, syntaxes, times, rodread, idgen, modulegraphs, reorder, rod,
|
||||||
configuration
|
lineinfos
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
import
|
import
|
||||||
os, platform, condsyms, ast, astalgo, idents, semdata, msgs, renderer,
|
os, platform, condsyms, ast, astalgo, idents, semdata, msgs, renderer,
|
||||||
wordrecg, ropes, options, strutils, extccomp, math, magicsys, trees,
|
wordrecg, ropes, options, strutils, extccomp, math, magicsys, trees,
|
||||||
rodread, types, lookups, configuration
|
rodread, types, lookups, lineinfos
|
||||||
|
|
||||||
const
|
const
|
||||||
FirstCallConv* = wNimcall
|
FirstCallConv* = wNimcall
|
||||||
|
|
@ -549,7 +549,7 @@ proc pragmaLine(c: PContext, n: PNode) =
|
||||||
localError(c.config, n.info, "tuple expected")
|
localError(c.config, n.info, "tuple expected")
|
||||||
else:
|
else:
|
||||||
# sensible default:
|
# sensible default:
|
||||||
n.info = getInfoContext(-1)
|
n.info = getInfoContext(c.config, -1)
|
||||||
|
|
||||||
proc processPragma(c: PContext, n: PNode, i: int) =
|
proc processPragma(c: PContext, n: PNode, i: int) =
|
||||||
let it = n[i]
|
let it = n[i]
|
||||||
|
|
@ -1047,13 +1047,13 @@ proc implicitPragmas*(c: PContext, sym: PSym, n: PNode,
|
||||||
for it in c.optionStack:
|
for it in c.optionStack:
|
||||||
let o = it.otherPragmas
|
let o = it.otherPragmas
|
||||||
if not o.isNil:
|
if not o.isNil:
|
||||||
pushInfoContext(n.info)
|
pushInfoContext(c.config, n.info)
|
||||||
var i = 0
|
var i = 0
|
||||||
while i < o.len():
|
while i < o.len():
|
||||||
if singlePragma(c, sym, o, i, validPragmas):
|
if singlePragma(c, sym, o, i, validPragmas):
|
||||||
internalError(c.config, n.info, "implicitPragmas")
|
internalError(c.config, n.info, "implicitPragmas")
|
||||||
inc i
|
inc i
|
||||||
popInfoContext()
|
popInfoContext(c.config)
|
||||||
|
|
||||||
if lfExportLib in sym.loc.flags and sfExportc notin sym.flags:
|
if lfExportLib in sym.loc.flags and sfExportc notin sym.flags:
|
||||||
localError(c.config, n.info, ".dynlib requires .exportc")
|
localError(c.config, n.info, ".dynlib requires .exportc")
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ proc prefixMatch*(p, s: string): PrefixMatch =
|
||||||
# check for prefix/contains:
|
# check for prefix/contains:
|
||||||
while i < L:
|
while i < L:
|
||||||
if s[i] == '_': inc i
|
if s[i] == '_': inc i
|
||||||
if eq(s[i], p[0]):
|
if i < L and eq(s[i], p[0]):
|
||||||
var ii = i+1
|
var ii = i+1
|
||||||
var jj = 1
|
var jj = 1
|
||||||
while ii < L and jj < p.len:
|
while ii < L and jj < p.len:
|
||||||
|
|
@ -43,10 +43,10 @@ proc prefixMatch*(p, s: string): PrefixMatch =
|
||||||
i = 1
|
i = 1
|
||||||
var j = 1
|
var j = 1
|
||||||
while i < s.len:
|
while i < s.len:
|
||||||
if s[i] == '_' and i < s.len-1:
|
if i < s.len-1 and s[i] == '_':
|
||||||
if j < p.len and eq(p[j], s[i+1]): inc j
|
if j < p.len and eq(p[j], s[i+1]): inc j
|
||||||
else: return PrefixMatch.None
|
else: return PrefixMatch.None
|
||||||
if s[i] in {'A'..'Z'} and s[i-1] notin {'A'..'Z'}:
|
if i < s.len and s[i] in {'A'..'Z'} and s[i-1] notin {'A'..'Z'}:
|
||||||
if j < p.len and eq(p[j], s[i]): inc j
|
if j < p.len and eq(p[j], s[i]): inc j
|
||||||
else: return PrefixMatch.None
|
else: return PrefixMatch.None
|
||||||
inc i
|
inc i
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
# This module implements the renderer of the standard Nim representation.
|
# This module implements the renderer of the standard Nim representation.
|
||||||
|
|
||||||
import
|
import
|
||||||
lexer, options, idents, strutils, ast, msgs, configuration
|
lexer, options, idents, strutils, ast, msgs, lineinfos
|
||||||
|
|
||||||
type
|
type
|
||||||
TRenderFlag* = enum
|
TRenderFlag* = enum
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
import
|
import
|
||||||
intsets, ast, idents, algorithm, renderer, parser, ospaths, strutils,
|
intsets, ast, idents, algorithm, renderer, parser, ospaths, strutils,
|
||||||
sequtils, msgs, modulegraphs, syntaxes, options, modulepaths, tables,
|
sequtils, msgs, modulegraphs, syntaxes, options, modulepaths, tables,
|
||||||
configuration
|
lineinfos
|
||||||
|
|
||||||
type
|
type
|
||||||
DepN = ref object
|
DepN = ref object
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
## This module implements the canonalization for the various caching mechanisms.
|
## This module implements the canonalization for the various caching mechanisms.
|
||||||
|
|
||||||
import ast, idgen, msgs
|
import ast, idgen, lineinfos, msgs
|
||||||
|
|
||||||
when not defined(nimSymbolfiles):
|
when not defined(nimSymbolfiles):
|
||||||
template setupModuleCache* = discard
|
template setupModuleCache* = discard
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@
|
||||||
import
|
import
|
||||||
os, options, strutils, nversion, ast, astalgo, msgs, platform, condsyms,
|
os, options, strutils, nversion, ast, astalgo, msgs, platform, condsyms,
|
||||||
ropes, idents, std / sha1, idgen, types, rodutils, memfiles, tables,
|
ropes, idents, std / sha1, idgen, types, rodutils, memfiles, tables,
|
||||||
configuration
|
lineinfos
|
||||||
|
|
||||||
type
|
type
|
||||||
TReasonForRecompile* = enum ## all the reasons that can trigger recompilation
|
TReasonForRecompile* = enum ## all the reasons that can trigger recompilation
|
||||||
|
|
@ -899,7 +899,7 @@ proc checkDep(fileIdx: FileIndex; cache: IdentCache; conf: ConfigRef): TReasonFo
|
||||||
# NOTE: we need to process the entire module graph so that no ID will
|
# NOTE: we need to process the entire module graph so that no ID will
|
||||||
# be used twice! However, compilation speed does not suffer much from
|
# be used twice! However, compilation speed does not suffer much from
|
||||||
# this, since results are cached.
|
# this, since results are cached.
|
||||||
var res = checkDep(systemFileIdx, cache, conf)
|
var res = checkDep(conf.m.systemFileIdx, cache, conf)
|
||||||
if res != rrNone: result = rrModDeps
|
if res != rrNone: result = rrModDeps
|
||||||
for i in countup(0, high(r.modDeps)):
|
for i in countup(0, high(r.modDeps)):
|
||||||
res = checkDep(r.modDeps[i], cache, conf)
|
res = checkDep(r.modDeps[i], cache, conf)
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
import
|
import
|
||||||
intsets, os, options, strutils, nversion, ast, astalgo, msgs, platform,
|
intsets, os, options, strutils, nversion, ast, astalgo, msgs, platform,
|
||||||
condsyms, ropes, idents, std / sha1, rodread, passes, idgen,
|
condsyms, ropes, idents, std / sha1, rodread, passes, idgen,
|
||||||
rodutils, modulepaths
|
rodutils, modulepaths, lineinfos
|
||||||
|
|
||||||
from modulegraphs import ModuleGraph
|
from modulegraphs import ModuleGraph
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@
|
||||||
# To cache them they are inserted in a `cache` array.
|
# To cache them they are inserted in a `cache` array.
|
||||||
|
|
||||||
import
|
import
|
||||||
platform, hashes
|
hashes
|
||||||
|
|
||||||
type
|
type
|
||||||
FormatStr* = string # later we may change it to CString for better
|
FormatStr* = string # later we may change it to CString for better
|
||||||
|
|
@ -70,8 +70,6 @@ type
|
||||||
length*: int
|
length*: int
|
||||||
data*: string # != nil if a leaf
|
data*: string # != nil if a leaf
|
||||||
|
|
||||||
RopeSeq* = seq[Rope]
|
|
||||||
|
|
||||||
proc len*(a: Rope): int =
|
proc len*(a: Rope): int =
|
||||||
## the rope's length
|
## the rope's length
|
||||||
if a == nil: result = 0
|
if a == nil: result = 0
|
||||||
|
|
@ -93,7 +91,7 @@ proc freezeMutableRope*(r: Rope) {.inline.} =
|
||||||
r.length = r.data.len
|
r.length = r.data.len
|
||||||
|
|
||||||
var
|
var
|
||||||
cache: array[0..2048*2 - 1, Rope]
|
cache: array[0..2048*2 - 1, Rope] # XXX Global here!
|
||||||
|
|
||||||
proc resetRopeCache* =
|
proc resetRopeCache* =
|
||||||
for i in low(cache)..high(cache):
|
for i in low(cache)..high(cache):
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
import
|
import
|
||||||
ast, modules, idents, passes, passaux, condsyms,
|
ast, modules, idents, passes, passaux, condsyms,
|
||||||
options, nimconf, sem, semdata, llstream, vm, vmdef, commands, msgs,
|
options, nimconf, sem, semdata, llstream, vm, vmdef, commands, msgs,
|
||||||
os, times, osproc, wordrecg, strtabs, modulegraphs, configuration
|
os, times, osproc, wordrecg, strtabs, modulegraphs, lineinfos
|
||||||
|
|
||||||
# we support 'cmpIgnoreStyle' natively for efficiency:
|
# we support 'cmpIgnoreStyle' natively for efficiency:
|
||||||
from strutils import cmpIgnoreStyle, contains
|
from strutils import cmpIgnoreStyle, contains
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import
|
||||||
procfind, lookups, rodread, pragmas, passes, semdata, semtypinst, sigmatch,
|
procfind, lookups, rodread, pragmas, passes, semdata, semtypinst, sigmatch,
|
||||||
intsets, transf, vmdef, vm, idgen, aliases, cgmeth, lambdalifting,
|
intsets, transf, vmdef, vm, idgen, aliases, cgmeth, lambdalifting,
|
||||||
evaltempl, patterns, parampatterns, sempass2, nimfix.pretty, semmacrosanity,
|
evaltempl, patterns, parampatterns, sempass2, nimfix.pretty, semmacrosanity,
|
||||||
semparallel, lowerings, pluginsupport, plugins.active, rod, configuration
|
semparallel, lowerings, pluginsupport, plugins.active, rod, lineinfos
|
||||||
|
|
||||||
from modulegraphs import ModuleGraph
|
from modulegraphs import ModuleGraph
|
||||||
|
|
||||||
|
|
@ -52,10 +52,10 @@ proc isArrayConstr(n: PNode): bool {.inline.} =
|
||||||
result = n.kind == nkBracket and
|
result = n.kind == nkBracket and
|
||||||
n.typ.skipTypes(abstractInst).kind == tyArray
|
n.typ.skipTypes(abstractInst).kind == tyArray
|
||||||
|
|
||||||
template semIdeForTemplateOrGenericCheck(n, requiresCheck) =
|
template semIdeForTemplateOrGenericCheck(conf, n, requiresCheck) =
|
||||||
# we check quickly if the node is where the cursor is
|
# we check quickly if the node is where the cursor is
|
||||||
when defined(nimsuggest):
|
when defined(nimsuggest):
|
||||||
if n.info.fileIndex == gTrackPos.fileIndex and n.info.line == gTrackPos.line:
|
if n.info.fileIndex == conf.m.trackPos.fileIndex and n.info.line == conf.m.trackPos.line:
|
||||||
requiresCheck = true
|
requiresCheck = true
|
||||||
|
|
||||||
template semIdeForTemplateOrGeneric(c: PContext; n: PNode;
|
template semIdeForTemplateOrGeneric(c: PContext; n: PNode;
|
||||||
|
|
@ -307,9 +307,9 @@ proc tryConstExpr(c: PContext, n: PNode): PNode =
|
||||||
|
|
||||||
let oldErrorCount = c.config.errorCounter
|
let oldErrorCount = c.config.errorCounter
|
||||||
let oldErrorMax = c.config.errorMax
|
let oldErrorMax = c.config.errorMax
|
||||||
let oldErrorOutputs = errorOutputs
|
let oldErrorOutputs = c.config.m.errorOutputs
|
||||||
|
|
||||||
errorOutputs = {}
|
c.config.m.errorOutputs = {}
|
||||||
c.config.errorMax = high(int)
|
c.config.errorMax = high(int)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
@ -324,7 +324,7 @@ proc tryConstExpr(c: PContext, n: PNode): PNode =
|
||||||
|
|
||||||
c.config.errorCounter = oldErrorCount
|
c.config.errorCounter = oldErrorCount
|
||||||
c.config.errorMax = oldErrorMax
|
c.config.errorMax = oldErrorMax
|
||||||
errorOutputs = oldErrorOutputs
|
c.config.m.errorOutputs = oldErrorOutputs
|
||||||
|
|
||||||
const
|
const
|
||||||
errConstExprExpected = "constant expression expected"
|
errConstExprExpected = "constant expression expected"
|
||||||
|
|
@ -340,9 +340,9 @@ proc semConstExpr(c: PContext, n: PNode): PNode =
|
||||||
result = evalConstExpr(c.module, c.cache, c.graph, e)
|
result = evalConstExpr(c.module, c.cache, c.graph, e)
|
||||||
if result == nil or result.kind == nkEmpty:
|
if result == nil or result.kind == nkEmpty:
|
||||||
if e.info != n.info:
|
if e.info != n.info:
|
||||||
pushInfoContext(n.info)
|
pushInfoContext(c.config, n.info)
|
||||||
localError(c.config, e.info, errConstExprExpected)
|
localError(c.config, e.info, errConstExprExpected)
|
||||||
popInfoContext()
|
popInfoContext(c.config)
|
||||||
else:
|
else:
|
||||||
localError(c.config, e.info, errConstExprExpected)
|
localError(c.config, e.info, errConstExprExpected)
|
||||||
# error correction:
|
# error correction:
|
||||||
|
|
@ -380,8 +380,8 @@ proc semAfterMacroCall(c: PContext, call, macroResult: PNode,
|
||||||
## coherence, making sure that variables declared with 'let' aren't
|
## coherence, making sure that variables declared with 'let' aren't
|
||||||
## reassigned, and binding the unbound identifiers that the macro output
|
## reassigned, and binding the unbound identifiers that the macro output
|
||||||
## contains.
|
## contains.
|
||||||
inc(evalTemplateCounter)
|
inc(c.config.evalTemplateCounter)
|
||||||
if evalTemplateCounter > evalTemplateLimit:
|
if c.config.evalTemplateCounter > evalTemplateLimit:
|
||||||
globalError(c.config, s.info, "template instantiation too nested")
|
globalError(c.config, s.info, "template instantiation too nested")
|
||||||
c.friendModules.add(s.owner.getModule)
|
c.friendModules.add(s.owner.getModule)
|
||||||
|
|
||||||
|
|
@ -420,8 +420,8 @@ proc semAfterMacroCall(c: PContext, call, macroResult: PNode,
|
||||||
|
|
||||||
result = semExpr(c, result, flags)
|
result = semExpr(c, result, flags)
|
||||||
result = fitNode(c, retType, result, result.info)
|
result = fitNode(c, retType, result, result.info)
|
||||||
#GlobalError(s.info, errInvalidParamKindX, typeToString(s.typ.sons[0]))
|
#globalError(s.info, errInvalidParamKindX, typeToString(s.typ.sons[0]))
|
||||||
dec(evalTemplateCounter)
|
dec(c.config.evalTemplateCounter)
|
||||||
discard c.friendModules.pop()
|
discard c.friendModules.pop()
|
||||||
|
|
||||||
const
|
const
|
||||||
|
|
@ -429,7 +429,7 @@ const
|
||||||
|
|
||||||
proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
|
proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
|
||||||
flags: TExprFlags = {}): PNode =
|
flags: TExprFlags = {}): PNode =
|
||||||
pushInfoContext(nOrig.info)
|
pushInfoContext(c.config, nOrig.info)
|
||||||
|
|
||||||
markUsed(c.config, n.info, sym, c.graph.usageSym)
|
markUsed(c.config, n.info, sym, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, sym)
|
styleCheckUse(n.info, sym)
|
||||||
|
|
@ -449,7 +449,7 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
|
||||||
if efNoSemCheck notin flags:
|
if efNoSemCheck notin flags:
|
||||||
result = semAfterMacroCall(c, n, result, sym, flags)
|
result = semAfterMacroCall(c, n, result, sym, flags)
|
||||||
result = wrapInComesFrom(nOrig.info, sym, result)
|
result = wrapInComesFrom(nOrig.info, sym, result)
|
||||||
popInfoContext()
|
popInfoContext(c.config)
|
||||||
|
|
||||||
proc forceBool(c: PContext, n: PNode): PNode =
|
proc forceBool(c: PContext, n: PNode): PNode =
|
||||||
result = fitNode(c, getSysType(c.graph, n.info, tyBool), n, n.info)
|
result = fitNode(c, getSysType(c.graph, n.info, tyBool), n, n.info)
|
||||||
|
|
@ -582,14 +582,14 @@ proc myProcess(context: PPassContext, n: PNode): PNode =
|
||||||
if c.config.errorMax <= 1:
|
if c.config.errorMax <= 1:
|
||||||
result = semStmtAndGenerateGenerics(c, n)
|
result = semStmtAndGenerateGenerics(c, n)
|
||||||
else:
|
else:
|
||||||
let oldContextLen = msgs.getInfoContextLen()
|
let oldContextLen = msgs.getInfoContextLen(c.config)
|
||||||
let oldInGenericInst = c.inGenericInst
|
let oldInGenericInst = c.inGenericInst
|
||||||
try:
|
try:
|
||||||
result = semStmtAndGenerateGenerics(c, n)
|
result = semStmtAndGenerateGenerics(c, n)
|
||||||
except ERecoverableError, ESuggestDone:
|
except ERecoverableError, ESuggestDone:
|
||||||
recoverContext(c)
|
recoverContext(c)
|
||||||
c.inGenericInst = oldInGenericInst
|
c.inGenericInst = oldInGenericInst
|
||||||
msgs.setInfoContextLen(oldContextLen)
|
msgs.setInfoContextLen(c.config, oldContextLen)
|
||||||
if getCurrentException() of ESuggestDone:
|
if getCurrentException() of ESuggestDone:
|
||||||
c.suggestionsMade = true
|
c.suggestionsMade = true
|
||||||
result = nil
|
result = nil
|
||||||
|
|
|
||||||
|
|
@ -213,7 +213,7 @@ proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) =
|
||||||
# Gives a detailed error message; this is separated from semOverloadedCall,
|
# Gives a detailed error message; this is separated from semOverloadedCall,
|
||||||
# as semOverlodedCall is already pretty slow (and we need this information
|
# as semOverlodedCall is already pretty slow (and we need this information
|
||||||
# only in case of an error).
|
# only in case of an error).
|
||||||
if errorOutputs == {}:
|
if c.config.m.errorOutputs == {}:
|
||||||
# fail fast:
|
# fail fast:
|
||||||
globalError(c.config, n.info, "type mismatch")
|
globalError(c.config, n.info, "type mismatch")
|
||||||
if errors.len == 0:
|
if errors.len == 0:
|
||||||
|
|
@ -332,7 +332,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
|
||||||
internalAssert c.config, result.state == csMatch
|
internalAssert c.config, result.state == csMatch
|
||||||
#writeMatches(result)
|
#writeMatches(result)
|
||||||
#writeMatches(alt)
|
#writeMatches(alt)
|
||||||
if errorOutputs == {}:
|
if c.config.m.errorOutputs == {}:
|
||||||
# quick error message for performance of 'compiles' built-in:
|
# quick error message for performance of 'compiles' built-in:
|
||||||
globalError(c.config, n.info, errGenerated, "ambiguous call")
|
globalError(c.config, n.info, errGenerated, "ambiguous call")
|
||||||
elif c.config.errorCounter == 0:
|
elif c.config.errorCounter == 0:
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import
|
||||||
wordrecg,
|
wordrecg,
|
||||||
ropes, msgs, platform, os, condsyms, idents, renderer, types, extccomp, math,
|
ropes, msgs, platform, os, condsyms, idents, renderer, types, extccomp, math,
|
||||||
magicsys, nversion, nimsets, parser, times, passes, rodread, vmdef,
|
magicsys, nversion, nimsets, parser, times, passes, rodread, vmdef,
|
||||||
modulegraphs, configuration
|
modulegraphs, lineinfos
|
||||||
|
|
||||||
type
|
type
|
||||||
TOptionEntry* = object # entries to put on a stack for pragma parsing
|
TOptionEntry* = object # entries to put on a stack for pragma parsing
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,10 @@ proc semTemplateExpr(c: PContext, n: PNode, s: PSym,
|
||||||
flags: TExprFlags = {}): PNode =
|
flags: TExprFlags = {}): PNode =
|
||||||
markUsed(c.config, n.info, s, c.graph.usageSym)
|
markUsed(c.config, n.info, s, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
pushInfoContext(n.info)
|
pushInfoContext(c.config, n.info)
|
||||||
result = evalTemplate(n, s, getCurrOwner(c), c.config, efFromHlo in flags)
|
result = evalTemplate(n, s, getCurrOwner(c), c.config, efFromHlo in flags)
|
||||||
if efNoSemCheck notin flags: result = semAfterMacroCall(c, n, result, s, flags)
|
if efNoSemCheck notin flags: result = semAfterMacroCall(c, n, result, s, flags)
|
||||||
popInfoContext()
|
popInfoContext(c.config)
|
||||||
|
|
||||||
proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
|
proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
|
||||||
|
|
||||||
|
|
@ -742,7 +742,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
# This is a proc variable, apply normal overload resolution
|
# This is a proc variable, apply normal overload resolution
|
||||||
let m = resolveIndirectCall(c, n, nOrig, t)
|
let m = resolveIndirectCall(c, n, nOrig, t)
|
||||||
if m.state != csMatch:
|
if m.state != csMatch:
|
||||||
if errorOutputs == {}:
|
if c.config.m.errorOutputs == {}:
|
||||||
# speed up error generation:
|
# speed up error generation:
|
||||||
globalError(c.config, n.info, "type mismatch")
|
globalError(c.config, n.info, "type mismatch")
|
||||||
return c.graph.emptyNode
|
return c.graph.emptyNode
|
||||||
|
|
@ -1082,7 +1082,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
when defined(nimsuggest):
|
when defined(nimsuggest):
|
||||||
if c.config.cmd == cmdIdeTools:
|
if c.config.cmd == cmdIdeTools:
|
||||||
suggestExpr(c, n)
|
suggestExpr(c, n)
|
||||||
if exactEquals(gTrackPos, n[1].info): suggestExprNoCheck(c, n)
|
if exactEquals(c.config.m.trackPos, n[1].info): suggestExprNoCheck(c, n)
|
||||||
|
|
||||||
var s = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared, checkModule})
|
var s = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared, checkModule})
|
||||||
if s != nil:
|
if s != nil:
|
||||||
|
|
@ -1783,9 +1783,9 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
openScope(c)
|
openScope(c)
|
||||||
let oldOwnerLen = len(c.graph.owners)
|
let oldOwnerLen = len(c.graph.owners)
|
||||||
let oldGenerics = c.generics
|
let oldGenerics = c.generics
|
||||||
let oldErrorOutputs = errorOutputs
|
let oldErrorOutputs = c.config.m.errorOutputs
|
||||||
if efExplain notin flags: errorOutputs = {}
|
if efExplain notin flags: c.config.m.errorOutputs = {}
|
||||||
let oldContextLen = msgs.getInfoContextLen()
|
let oldContextLen = msgs.getInfoContextLen(c.config)
|
||||||
|
|
||||||
let oldInGenericContext = c.inGenericContext
|
let oldInGenericContext = c.inGenericContext
|
||||||
let oldInUnrolledContext = c.inUnrolledContext
|
let oldInUnrolledContext = c.inUnrolledContext
|
||||||
|
|
@ -1807,10 +1807,10 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
c.inGenericInst = oldInGenericInst
|
c.inGenericInst = oldInGenericInst
|
||||||
c.inStaticContext = oldInStaticContext
|
c.inStaticContext = oldInStaticContext
|
||||||
c.p = oldProcCon
|
c.p = oldProcCon
|
||||||
msgs.setInfoContextLen(oldContextLen)
|
msgs.setInfoContextLen(c.config, oldContextLen)
|
||||||
setLen(c.graph.owners, oldOwnerLen)
|
setLen(c.graph.owners, oldOwnerLen)
|
||||||
c.currentScope = oldScope
|
c.currentScope = oldScope
|
||||||
errorOutputs = oldErrorOutputs
|
c.config.m.errorOutputs = oldErrorOutputs
|
||||||
c.config.errorCounter = oldErrorCount
|
c.config.errorCounter = oldErrorCount
|
||||||
c.config.errorMax = oldErrorMax
|
c.config.errorMax = oldErrorMax
|
||||||
|
|
||||||
|
|
@ -2309,7 +2309,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
# check if it is an expression macro:
|
# check if it is an expression macro:
|
||||||
checkMinSonsLen(n, 1, c.config)
|
checkMinSonsLen(n, 1, c.config)
|
||||||
#when defined(nimsuggest):
|
#when defined(nimsuggest):
|
||||||
# if gIdeCmd == ideCon and gTrackPos == n.info: suggestExprNoCheck(c, n)
|
# if gIdeCmd == ideCon and c.config.m.trackPos == n.info: suggestExprNoCheck(c, n)
|
||||||
let mode = if nfDotField in n.flags: {} else: {checkUndeclared}
|
let mode = if nfDotField in n.flags: {} else: {checkUndeclared}
|
||||||
var s = qualifiedLookUp(c, n.sons[0], mode)
|
var s = qualifiedLookUp(c, n.sons[0], mode)
|
||||||
if s != nil:
|
if s != nil:
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
import
|
import
|
||||||
strutils, options, ast, astalgo, trees, treetab, nimsets, times,
|
strutils, options, ast, astalgo, trees, treetab, nimsets, times,
|
||||||
nversion, platform, math, msgs, os, condsyms, idents, renderer, types,
|
nversion, platform, math, msgs, os, condsyms, idents, renderer, types,
|
||||||
commands, magicsys, modulegraphs, strtabs
|
commands, magicsys, modulegraphs, strtabs, lineinfos
|
||||||
|
|
||||||
proc newIntNodeT*(intVal: BiggestInt, n: PNode; g: ModuleGraph): PNode =
|
proc newIntNodeT*(intVal: BiggestInt, n: PNode; g: ModuleGraph): PNode =
|
||||||
case skipTypes(n.typ, abstractVarRange).kind
|
case skipTypes(n.typ, abstractVarRange).kind
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ template macroToExpandSym(s): untyped =
|
||||||
|
|
||||||
proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym,
|
proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym,
|
||||||
ctx: var GenericCtx; fromDotExpr=false): PNode =
|
ctx: var GenericCtx; fromDotExpr=false): PNode =
|
||||||
semIdeForTemplateOrGenericCheck(n, ctx.cursorInBody)
|
semIdeForTemplateOrGenericCheck(c.config, n, ctx.cursorInBody)
|
||||||
incl(s.flags, sfUsed)
|
incl(s.flags, sfUsed)
|
||||||
case s.kind
|
case s.kind
|
||||||
of skUnknown:
|
of skUnknown:
|
||||||
|
|
@ -129,7 +129,7 @@ proc newDot(n, b: PNode): PNode =
|
||||||
proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags,
|
proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags,
|
||||||
ctx: var GenericCtx; isMacro: var bool): PNode =
|
ctx: var GenericCtx; isMacro: var bool): PNode =
|
||||||
assert n.kind == nkDotExpr
|
assert n.kind == nkDotExpr
|
||||||
semIdeForTemplateOrGenericCheck(n, ctx.cursorInBody)
|
semIdeForTemplateOrGenericCheck(c.config, n, ctx.cursorInBody)
|
||||||
|
|
||||||
let luf = if withinMixin notin flags: {checkUndeclared, checkModule} else: {checkModule}
|
let luf = if withinMixin notin flags: {checkUndeclared, checkModule} else: {checkModule}
|
||||||
|
|
||||||
|
|
@ -170,7 +170,7 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||||
if withinTypeDesc in flags: inc c.inTypeContext
|
if withinTypeDesc in flags: inc c.inTypeContext
|
||||||
|
|
||||||
#if conf.cmd == cmdIdeTools: suggestStmt(c, n)
|
#if conf.cmd == cmdIdeTools: suggestStmt(c, n)
|
||||||
semIdeForTemplateOrGenericCheck(n, ctx.cursorInBody)
|
semIdeForTemplateOrGenericCheck(c.config, n, ctx.cursorInBody)
|
||||||
|
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkIdent, nkAccQuoted:
|
of nkIdent, nkAccQuoted:
|
||||||
|
|
|
||||||
|
|
@ -159,13 +159,13 @@ proc fixupInstantiatedSymbols(c: PContext, s: PSym) =
|
||||||
var oldPrc = c.generics[i].inst.sym
|
var oldPrc = c.generics[i].inst.sym
|
||||||
pushProcCon(c, oldPrc)
|
pushProcCon(c, oldPrc)
|
||||||
pushOwner(c, oldPrc)
|
pushOwner(c, oldPrc)
|
||||||
pushInfoContext(oldPrc.info)
|
pushInfoContext(c.config, oldPrc.info)
|
||||||
openScope(c)
|
openScope(c)
|
||||||
var n = oldPrc.ast
|
var n = oldPrc.ast
|
||||||
n.sons[bodyPos] = copyTree(s.getBody)
|
n.sons[bodyPos] = copyTree(s.getBody)
|
||||||
instantiateBody(c, n, oldPrc.typ.n, oldPrc, s)
|
instantiateBody(c, n, oldPrc.typ.n, oldPrc, s)
|
||||||
closeScope(c)
|
closeScope(c)
|
||||||
popInfoContext()
|
popInfoContext(c.config)
|
||||||
popOwner(c)
|
popOwner(c)
|
||||||
popProcCon(c)
|
popProcCon(c)
|
||||||
|
|
||||||
|
|
@ -236,7 +236,7 @@ proc instantiateProcType(c: PContext, pt: TIdTable,
|
||||||
# at this point semtypinst have to become part of sem, because it
|
# at this point semtypinst have to become part of sem, because it
|
||||||
# will need to use openScope, addDecl, etc.
|
# will need to use openScope, addDecl, etc.
|
||||||
#addDecl(c, prc)
|
#addDecl(c, prc)
|
||||||
pushInfoContext(info)
|
pushInfoContext(c.config, info)
|
||||||
var typeMap = initLayeredTypeMap(pt)
|
var typeMap = initLayeredTypeMap(pt)
|
||||||
var cl = initTypeVars(c, addr(typeMap), info, nil)
|
var cl = initTypeVars(c, addr(typeMap), info, nil)
|
||||||
var result = instCopyType(cl, prc.typ)
|
var result = instCopyType(cl, prc.typ)
|
||||||
|
|
@ -278,7 +278,7 @@ proc instantiateProcType(c: PContext, pt: TIdTable,
|
||||||
skipIntLiteralParams(result)
|
skipIntLiteralParams(result)
|
||||||
|
|
||||||
prc.typ = result
|
prc.typ = result
|
||||||
popInfoContext()
|
popInfoContext(c.config)
|
||||||
|
|
||||||
proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
||||||
info: TLineInfo): PSym =
|
info: TLineInfo): PSym =
|
||||||
|
|
@ -309,7 +309,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
||||||
let gp = n.sons[genericParamsPos]
|
let gp = n.sons[genericParamsPos]
|
||||||
internalAssert c.config, gp.kind != nkEmpty
|
internalAssert c.config, gp.kind != nkEmpty
|
||||||
n.sons[namePos] = newSymNode(result)
|
n.sons[namePos] = newSymNode(result)
|
||||||
pushInfoContext(info)
|
pushInfoContext(c.config, info)
|
||||||
var entry = TInstantiation.new
|
var entry = TInstantiation.new
|
||||||
entry.sym = result
|
entry.sym = result
|
||||||
# we need to compare both the generic types and the concrete types:
|
# we need to compare both the generic types and the concrete types:
|
||||||
|
|
@ -353,7 +353,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
||||||
else:
|
else:
|
||||||
result = oldPrc
|
result = oldPrc
|
||||||
popProcCon(c)
|
popProcCon(c)
|
||||||
popInfoContext()
|
popInfoContext(c.config)
|
||||||
closeScope(c) # close scope for parameters
|
closeScope(c) # close scope for parameters
|
||||||
popOwner(c)
|
popOwner(c)
|
||||||
c.currentScope = oldScope
|
c.currentScope = oldScope
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ proc semInstantiationInfo(c: PContext, n: PNode): PNode =
|
||||||
result = newNodeIT(nkTupleConstr, n.info, n.typ)
|
result = newNodeIT(nkTupleConstr, n.info, n.typ)
|
||||||
let idx = expectIntLit(c, n.sons[1])
|
let idx = expectIntLit(c, n.sons[1])
|
||||||
let useFullPaths = expectIntLit(c, n.sons[2])
|
let useFullPaths = expectIntLit(c, n.sons[2])
|
||||||
let info = getInfoContext(idx)
|
let info = getInfoContext(c.config, idx)
|
||||||
var filename = newNodeIT(nkStrLit, n.info, getSysType(c.graph, n.info, tyString))
|
var filename = newNodeIT(nkStrLit, n.info, getSysType(c.graph, n.info, tyString))
|
||||||
filename.strVal = if useFullPaths != 0: toFullPath(c.config, info) else: toFilename(c.config, info)
|
filename.strVal = if useFullPaths != 0: toFullPath(c.config, info) else: toFilename(c.config, info)
|
||||||
var line = newNodeIT(nkIntLit, n.info, getSysType(c.graph, n.info, tyInt))
|
var line = newNodeIT(nkIntLit, n.info, getSysType(c.graph, n.info, tyInt))
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees,
|
intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees,
|
||||||
wordrecg, strutils, options, guards, writetracking, configuration,
|
wordrecg, strutils, options, guards, writetracking, lineinfos,
|
||||||
modulegraphs
|
modulegraphs
|
||||||
|
|
||||||
when defined(useDfa):
|
when defined(useDfa):
|
||||||
|
|
@ -859,9 +859,9 @@ proc checkRaisesSpec(g: ModuleGraph; spec, real: PNode, msg: string, hints: bool
|
||||||
used.incl(s)
|
used.incl(s)
|
||||||
break search
|
break search
|
||||||
# XXX call graph analysis would be nice here!
|
# XXX call graph analysis would be nice here!
|
||||||
pushInfoContext(spec.info)
|
pushInfoContext(g.config, spec.info)
|
||||||
localError(g.config, r.info, errGenerated, msg & typeToString(r.typ))
|
localError(g.config, r.info, errGenerated, msg & typeToString(r.typ))
|
||||||
popInfoContext()
|
popInfoContext(g.config)
|
||||||
# hint about unnecessarily listed exception types:
|
# hint about unnecessarily listed exception types:
|
||||||
if hints:
|
if hints:
|
||||||
for s in 0 ..< spec.len:
|
for s in 0 ..< spec.len:
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ proc semWhile(c: PContext, n: PNode): PNode =
|
||||||
result.typ = c.enforceVoidContext
|
result.typ = c.enforceVoidContext
|
||||||
|
|
||||||
proc toCover(c: PContext, t: PType): BiggestInt =
|
proc toCover(c: PContext, t: PType): BiggestInt =
|
||||||
var t2 = skipTypes(t, abstractVarRange-{tyTypeDesc})
|
let t2 = skipTypes(t, abstractVarRange-{tyTypeDesc})
|
||||||
if t2.kind == tyEnum and enumHasHoles(t2):
|
if t2.kind == tyEnum and enumHasHoles(t2):
|
||||||
result = sonsLen(t2.n)
|
result = sonsLen(t2.n)
|
||||||
else:
|
else:
|
||||||
|
|
@ -201,7 +201,7 @@ proc semCase(c: PContext, n: PNode): PNode =
|
||||||
for i in countup(1, sonsLen(n) - 1):
|
for i in countup(1, sonsLen(n) - 1):
|
||||||
var x = n.sons[i]
|
var x = n.sons[i]
|
||||||
when defined(nimsuggest):
|
when defined(nimsuggest):
|
||||||
if c.config.ideCmd == ideSug and exactEquals(gTrackPos, x.info) and caseTyp.kind == tyEnum:
|
if c.config.ideCmd == ideSug and exactEquals(c.config.m.trackPos, x.info) and caseTyp.kind == tyEnum:
|
||||||
suggestEnum(c, x, caseTyp)
|
suggestEnum(c, x, caseTyp)
|
||||||
case x.kind
|
case x.kind
|
||||||
of nkOfBranch:
|
of nkOfBranch:
|
||||||
|
|
@ -1396,14 +1396,14 @@ proc semOverride(c: PContext, s: PSym, n: PNode) =
|
||||||
localError(c.config, n.info, errGenerated,
|
localError(c.config, n.info, errGenerated,
|
||||||
"'destroy' or 'deepCopy' expected for 'override'")
|
"'destroy' or 'deepCopy' expected for 'override'")
|
||||||
|
|
||||||
proc cursorInProcAux(n: PNode): bool =
|
proc cursorInProcAux(conf: ConfigRef; n: PNode): bool =
|
||||||
if inCheckpoint(n.info) != cpNone: return true
|
if inCheckpoint(n.info, conf.m.trackPos) != cpNone: return true
|
||||||
for i in 0..<n.safeLen:
|
for i in 0..<n.safeLen:
|
||||||
if cursorInProcAux(n[i]): return true
|
if cursorInProcAux(conf, n[i]): return true
|
||||||
|
|
||||||
proc cursorInProc(n: PNode): bool =
|
proc cursorInProc(conf: ConfigRef; n: PNode): bool =
|
||||||
if n.info.fileIndex == gTrackPos.fileIndex:
|
if n.info.fileIndex == conf.m.trackPos.fileIndex:
|
||||||
result = cursorInProcAux(n)
|
result = cursorInProcAux(conf, n)
|
||||||
|
|
||||||
type
|
type
|
||||||
TProcCompilationSteps = enum
|
TProcCompilationSteps = enum
|
||||||
|
|
@ -1583,7 +1583,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||||
# only used for overload resolution (there is no instantiation of
|
# only used for overload resolution (there is no instantiation of
|
||||||
# the symbol, so we must process the body now)
|
# the symbol, so we must process the body now)
|
||||||
if not usePseudoGenerics and c.config.ideCmd in {ideSug, ideCon} and not
|
if not usePseudoGenerics and c.config.ideCmd in {ideSug, ideCon} and not
|
||||||
cursorInProc(n.sons[bodyPos]):
|
cursorInProc(c.config, n.sons[bodyPos]):
|
||||||
discard "speed up nimsuggest"
|
discard "speed up nimsuggest"
|
||||||
if s.kind == skMethod: semMethodPrototype(c, s, n)
|
if s.kind == skMethod: semMethodPrototype(c, s, n)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -305,7 +305,7 @@ proc semTemplBodySons(c: var TemplCtx, n: PNode): PNode =
|
||||||
|
|
||||||
proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
|
proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
|
||||||
result = n
|
result = n
|
||||||
semIdeForTemplateOrGenericCheck(n, c.cursorInBody)
|
semIdeForTemplateOrGenericCheck(c.c.config, n, c.cursorInBody)
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkIdent:
|
of nkIdent:
|
||||||
if n.ident.id in c.toInject: return n
|
if n.ident.id in c.toInject: return n
|
||||||
|
|
@ -518,7 +518,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
|
||||||
|
|
||||||
proc semTemplBodyDirty(c: var TemplCtx, n: PNode): PNode =
|
proc semTemplBodyDirty(c: var TemplCtx, n: PNode): PNode =
|
||||||
result = n
|
result = n
|
||||||
semIdeForTemplateOrGenericCheck(n, c.cursorInBody)
|
semIdeForTemplateOrGenericCheck(c.c.config, n, c.cursorInBody)
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkIdent:
|
of nkIdent:
|
||||||
let s = qualifiedLookUp(c.c, n, {})
|
let s = qualifiedLookUp(c.c, n, {})
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@
|
||||||
|
|
||||||
# This module does the instantiation of generic types.
|
# This module does the instantiation of generic types.
|
||||||
|
|
||||||
import ast, astalgo, msgs, types, magicsys, semdata, renderer, options
|
import ast, astalgo, msgs, types, magicsys, semdata, renderer, options,
|
||||||
|
lineinfos
|
||||||
|
|
||||||
const
|
const
|
||||||
tfInstClearedFlags = {tfHasMeta, tfUnresolved}
|
tfInstClearedFlags = {tfHasMeta, tfUnresolved}
|
||||||
|
|
@ -568,35 +569,35 @@ proc replaceTypesInBody*(p: PContext, pt: TIdTable, n: PNode;
|
||||||
var typeMap = initLayeredTypeMap(pt)
|
var typeMap = initLayeredTypeMap(pt)
|
||||||
var cl = initTypeVars(p, addr(typeMap), n.info, owner)
|
var cl = initTypeVars(p, addr(typeMap), n.info, owner)
|
||||||
cl.allowMetaTypes = allowMetaTypes
|
cl.allowMetaTypes = allowMetaTypes
|
||||||
pushInfoContext(n.info)
|
pushInfoContext(p.config, n.info)
|
||||||
result = replaceTypeVarsN(cl, n)
|
result = replaceTypeVarsN(cl, n)
|
||||||
popInfoContext()
|
popInfoContext(p.config)
|
||||||
|
|
||||||
proc replaceTypesForLambda*(p: PContext, pt: TIdTable, n: PNode;
|
proc replaceTypesForLambda*(p: PContext, pt: TIdTable, n: PNode;
|
||||||
original, new: PSym): PNode =
|
original, new: PSym): PNode =
|
||||||
var typeMap = initLayeredTypeMap(pt)
|
var typeMap = initLayeredTypeMap(pt)
|
||||||
var cl = initTypeVars(p, addr(typeMap), n.info, original)
|
var cl = initTypeVars(p, addr(typeMap), n.info, original)
|
||||||
idTablePut(cl.symMap, original, new)
|
idTablePut(cl.symMap, original, new)
|
||||||
pushInfoContext(n.info)
|
pushInfoContext(p.config, n.info)
|
||||||
result = replaceTypeVarsN(cl, n)
|
result = replaceTypeVarsN(cl, n)
|
||||||
popInfoContext()
|
popInfoContext(p.config)
|
||||||
|
|
||||||
proc generateTypeInstance*(p: PContext, pt: TIdTable, info: TLineInfo,
|
proc generateTypeInstance*(p: PContext, pt: TIdTable, info: TLineInfo,
|
||||||
t: PType): PType =
|
t: PType): PType =
|
||||||
var typeMap = initLayeredTypeMap(pt)
|
var typeMap = initLayeredTypeMap(pt)
|
||||||
var cl = initTypeVars(p, addr(typeMap), info, nil)
|
var cl = initTypeVars(p, addr(typeMap), info, nil)
|
||||||
pushInfoContext(info)
|
pushInfoContext(p.config, info)
|
||||||
result = replaceTypeVarsT(cl, t)
|
result = replaceTypeVarsT(cl, t)
|
||||||
popInfoContext()
|
popInfoContext(p.config)
|
||||||
|
|
||||||
proc prepareMetatypeForSigmatch*(p: PContext, pt: TIdTable, info: TLineInfo,
|
proc prepareMetatypeForSigmatch*(p: PContext, pt: TIdTable, info: TLineInfo,
|
||||||
t: PType): PType =
|
t: PType): PType =
|
||||||
var typeMap = initLayeredTypeMap(pt)
|
var typeMap = initLayeredTypeMap(pt)
|
||||||
var cl = initTypeVars(p, addr(typeMap), info, nil)
|
var cl = initTypeVars(p, addr(typeMap), info, nil)
|
||||||
cl.allowMetaTypes = true
|
cl.allowMetaTypes = true
|
||||||
pushInfoContext(info)
|
pushInfoContext(p.config, info)
|
||||||
result = replaceTypeVarsT(cl, t)
|
result = replaceTypeVarsT(cl, t)
|
||||||
popInfoContext()
|
popInfoContext(p.config)
|
||||||
|
|
||||||
template generateTypeInstance*(p: PContext, pt: TIdTable, arg: PNode,
|
template generateTypeInstance*(p: PContext, pt: TIdTable, arg: PNode,
|
||||||
t: PType): untyped =
|
t: PType): untyped =
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
times, commands, options, msgs, nimconf,
|
times, commands, options, msgs, nimconf,
|
||||||
extccomp, strutils, os, platform, parseopt, idents, configuration
|
extccomp, strutils, os, platform, parseopt, idents, lineinfos
|
||||||
|
|
||||||
when useCaas:
|
when useCaas:
|
||||||
import net
|
import net
|
||||||
|
|
@ -71,7 +71,7 @@ proc serve*(cache: IdentCache; action: proc (cache: IdentCache){.nimcall.}; conf
|
||||||
var inp = "".TaintedString
|
var inp = "".TaintedString
|
||||||
server.listen()
|
server.listen()
|
||||||
var stdoutSocket = newSocket()
|
var stdoutSocket = newSocket()
|
||||||
msgs.writelnHook = proc (line: string) =
|
config.writelnHook = proc (line: string) =
|
||||||
stdoutSocket.send(line & "\c\L")
|
stdoutSocket.send(line & "\c\L")
|
||||||
|
|
||||||
while true:
|
while true:
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
import
|
import
|
||||||
intsets, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst,
|
intsets, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst,
|
||||||
magicsys, condsyms, idents, lexer, options, parampatterns, strutils, trees,
|
magicsys, condsyms, idents, lexer, options, parampatterns, strutils, trees,
|
||||||
nimfix.pretty
|
nimfix / pretty, lineinfos
|
||||||
|
|
||||||
when not defined(noDocgen):
|
when not defined(noDocgen):
|
||||||
import docgen
|
import docgen
|
||||||
|
|
@ -722,7 +722,7 @@ proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType =
|
||||||
addDecl(c, param)
|
addDecl(c, param)
|
||||||
|
|
||||||
var
|
var
|
||||||
oldWriteHook: type(writelnHook)
|
oldWriteHook: type(m.c.config.writelnHook)
|
||||||
diagnostics: seq[string]
|
diagnostics: seq[string]
|
||||||
errorPrefix: string
|
errorPrefix: string
|
||||||
flags: TExprFlags = {}
|
flags: TExprFlags = {}
|
||||||
|
|
@ -730,12 +730,12 @@ proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType =
|
||||||
sfExplain in typeClass.sym.flags
|
sfExplain in typeClass.sym.flags
|
||||||
|
|
||||||
if collectDiagnostics:
|
if collectDiagnostics:
|
||||||
oldWriteHook = writelnHook
|
oldWriteHook = m.c.config.writelnHook
|
||||||
# XXX: we can't write to m.diagnostics directly, because
|
# XXX: we can't write to m.diagnostics directly, because
|
||||||
# Nim doesn't support capturing var params in closures
|
# Nim doesn't support capturing var params in closures
|
||||||
diagnostics = @[]
|
diagnostics = @[]
|
||||||
flags = {efExplain}
|
flags = {efExplain}
|
||||||
writelnHook = proc (s: string) =
|
m.c.config.writelnHook = proc (s: string) =
|
||||||
if errorPrefix == nil: errorPrefix = typeClass.sym.name.s & ":"
|
if errorPrefix == nil: errorPrefix = typeClass.sym.name.s & ":"
|
||||||
let msg = s.replace("Error:", errorPrefix)
|
let msg = s.replace("Error:", errorPrefix)
|
||||||
if oldWriteHook != nil: oldWriteHook msg
|
if oldWriteHook != nil: oldWriteHook msg
|
||||||
|
|
@ -744,7 +744,7 @@ proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType =
|
||||||
var checkedBody = c.semTryExpr(c, body.copyTree, flags)
|
var checkedBody = c.semTryExpr(c, body.copyTree, flags)
|
||||||
|
|
||||||
if collectDiagnostics:
|
if collectDiagnostics:
|
||||||
writelnHook = oldWriteHook
|
m.c.config.writelnHook = oldWriteHook
|
||||||
for msg in diagnostics:
|
for msg in diagnostics:
|
||||||
m.diagnostics.safeAdd msg
|
m.diagnostics.safeAdd msg
|
||||||
m.diagnosticsEnabled = true
|
m.diagnosticsEnabled = true
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
# included from sigmatch.nim
|
# included from sigmatch.nim
|
||||||
|
|
||||||
import algorithm, prefixmatches, configuration
|
import algorithm, prefixmatches, lineinfos
|
||||||
from wordrecg import wDeprecated
|
from wordrecg import wDeprecated
|
||||||
|
|
||||||
when defined(nimsuggest):
|
when defined(nimsuggest):
|
||||||
|
|
@ -41,31 +41,6 @@ when defined(nimsuggest):
|
||||||
const
|
const
|
||||||
sep = '\t'
|
sep = '\t'
|
||||||
|
|
||||||
type
|
|
||||||
Suggest* = ref object
|
|
||||||
section*: IdeCmd
|
|
||||||
qualifiedPath*: seq[string]
|
|
||||||
name*: PIdent # not used beyond sorting purposes; name is also
|
|
||||||
# part of 'qualifiedPath'
|
|
||||||
filePath*: string
|
|
||||||
line*: int # Starts at 1
|
|
||||||
column*: int # Starts at 0
|
|
||||||
doc*: string # Not escaped (yet)
|
|
||||||
symkind*: TSymKind
|
|
||||||
forth*: string # type
|
|
||||||
quality*: range[0..100] # matching quality
|
|
||||||
isGlobal*: bool # is a global variable
|
|
||||||
contextFits*: bool # type/non-type context matches
|
|
||||||
prefix*: PrefixMatch
|
|
||||||
scope*, localUsages*, globalUsages*: int # more usages is better
|
|
||||||
tokenLen*: int
|
|
||||||
Suggestions* = seq[Suggest]
|
|
||||||
|
|
||||||
var
|
|
||||||
suggestionResultHook*: proc (result: Suggest) {.closure.}
|
|
||||||
suggestVersion*: int
|
|
||||||
suggestMaxResults* = 10_000
|
|
||||||
|
|
||||||
#template sectionSuggest(): expr = "##begin\n" & getStackTrace() & "##end\n"
|
#template sectionSuggest(): expr = "##begin\n" & getStackTrace() & "##end\n"
|
||||||
|
|
||||||
template origModuleName(m: PSym): string = m.name.s
|
template origModuleName(m: PSym): string = m.name.s
|
||||||
|
|
@ -104,7 +79,7 @@ proc cmpSuggestions(a, b: Suggest): int =
|
||||||
cf globalUsages
|
cf globalUsages
|
||||||
# if all is equal, sort alphabetically for deterministic output,
|
# if all is equal, sort alphabetically for deterministic output,
|
||||||
# independent of hashing order:
|
# independent of hashing order:
|
||||||
result = cmp(a.name.s, b.name.s)
|
result = cmp(a.name[], b.name[])
|
||||||
|
|
||||||
proc symToSuggest(conf: ConfigRef; s: PSym, isLocal: bool, section: IdeCmd, info: TLineInfo;
|
proc symToSuggest(conf: ConfigRef; s: PSym, isLocal: bool, section: IdeCmd, info: TLineInfo;
|
||||||
quality: range[0..100]; prefix: PrefixMatch;
|
quality: range[0..100]; prefix: PrefixMatch;
|
||||||
|
|
@ -117,14 +92,14 @@ proc symToSuggest(conf: ConfigRef; s: PSym, isLocal: bool, section: IdeCmd, info
|
||||||
result.prefix = prefix
|
result.prefix = prefix
|
||||||
result.contextFits = inTypeContext == (s.kind in {skType, skGenericParam})
|
result.contextFits = inTypeContext == (s.kind in {skType, skGenericParam})
|
||||||
result.scope = scope
|
result.scope = scope
|
||||||
result.name = s.name
|
result.name = addr s.name.s
|
||||||
when defined(nimsuggest):
|
when defined(nimsuggest):
|
||||||
result.globalUsages = s.allUsages.len
|
result.globalUsages = s.allUsages.len
|
||||||
var c = 0
|
var c = 0
|
||||||
for u in s.allUsages:
|
for u in s.allUsages:
|
||||||
if u.fileIndex == info.fileIndex: inc c
|
if u.fileIndex == info.fileIndex: inc c
|
||||||
result.localUsages = c
|
result.localUsages = c
|
||||||
result.symkind = s.kind
|
result.symkind = byte s.kind
|
||||||
if optIdeTerse notin conf.globalOptions:
|
if optIdeTerse notin conf.globalOptions:
|
||||||
result.qualifiedPath = @[]
|
result.qualifiedPath = @[]
|
||||||
if not isLocal and s.kind != skModule:
|
if not isLocal and s.kind != skModule:
|
||||||
|
|
@ -146,17 +121,18 @@ proc symToSuggest(conf: ConfigRef; s: PSym, isLocal: bool, section: IdeCmd, info
|
||||||
result.filePath = toFullPath(conf, infox)
|
result.filePath = toFullPath(conf, infox)
|
||||||
result.line = toLinenumber(infox)
|
result.line = toLinenumber(infox)
|
||||||
result.column = toColumn(infox)
|
result.column = toColumn(infox)
|
||||||
|
result.version = conf.suggestVersion
|
||||||
|
|
||||||
proc `$`*(suggest: Suggest): string =
|
proc `$`*(suggest: Suggest): string =
|
||||||
result = $suggest.section
|
result = $suggest.section
|
||||||
result.add(sep)
|
result.add(sep)
|
||||||
if suggest.section == ideHighlight:
|
if suggest.section == ideHighlight:
|
||||||
if suggest.symkind == skVar and suggest.isGlobal:
|
if suggest.symkind.TSymKind == skVar and suggest.isGlobal:
|
||||||
result.add("skGlobalVar")
|
result.add("skGlobalVar")
|
||||||
elif suggest.symkind == skLet and suggest.isGlobal:
|
elif suggest.symkind.TSymKind == skLet and suggest.isGlobal:
|
||||||
result.add("skGlobalLet")
|
result.add("skGlobalLet")
|
||||||
else:
|
else:
|
||||||
result.add($suggest.symkind)
|
result.add($suggest.symkind.TSymKind)
|
||||||
result.add(sep)
|
result.add(sep)
|
||||||
result.add($suggest.line)
|
result.add($suggest.line)
|
||||||
result.add(sep)
|
result.add(sep)
|
||||||
|
|
@ -164,9 +140,9 @@ proc `$`*(suggest: Suggest): string =
|
||||||
result.add(sep)
|
result.add(sep)
|
||||||
result.add($suggest.tokenLen)
|
result.add($suggest.tokenLen)
|
||||||
else:
|
else:
|
||||||
result.add($suggest.symkind)
|
result.add($suggest.symkind.TSymKind)
|
||||||
result.add(sep)
|
result.add(sep)
|
||||||
if suggest.qualifiedPath != nil:
|
if suggest.qualifiedPath.len != 0:
|
||||||
result.add(suggest.qualifiedPath.join("."))
|
result.add(suggest.qualifiedPath.join("."))
|
||||||
result.add(sep)
|
result.add(sep)
|
||||||
result.add(suggest.forth)
|
result.add(suggest.forth)
|
||||||
|
|
@ -179,18 +155,18 @@ proc `$`*(suggest: Suggest): string =
|
||||||
result.add(sep)
|
result.add(sep)
|
||||||
when not defined(noDocgen):
|
when not defined(noDocgen):
|
||||||
result.add(suggest.doc.escape)
|
result.add(suggest.doc.escape)
|
||||||
if suggestVersion == 0:
|
if suggest.version == 0:
|
||||||
result.add(sep)
|
result.add(sep)
|
||||||
result.add($suggest.quality)
|
result.add($suggest.quality)
|
||||||
if suggest.section == ideSug:
|
if suggest.section == ideSug:
|
||||||
result.add(sep)
|
result.add(sep)
|
||||||
result.add($suggest.prefix)
|
result.add($suggest.prefix)
|
||||||
|
|
||||||
proc suggestResult(s: Suggest) =
|
proc suggestResult(conf: ConfigRef; s: Suggest) =
|
||||||
if not isNil(suggestionResultHook):
|
if not isNil(conf.suggestionResultHook):
|
||||||
suggestionResultHook(s)
|
conf.suggestionResultHook(s)
|
||||||
else:
|
else:
|
||||||
suggestWriteln($s)
|
conf.suggestWriteln($s)
|
||||||
|
|
||||||
proc produceOutput(a: var Suggestions; conf: ConfigRef) =
|
proc produceOutput(a: var Suggestions; conf: ConfigRef) =
|
||||||
if conf.ideCmd in {ideSug, ideCon}:
|
if conf.ideCmd in {ideSug, ideCon}:
|
||||||
|
|
@ -198,13 +174,13 @@ proc produceOutput(a: var Suggestions; conf: ConfigRef) =
|
||||||
when defined(debug):
|
when defined(debug):
|
||||||
# debug code
|
# debug code
|
||||||
writeStackTrace()
|
writeStackTrace()
|
||||||
if a.len > suggestMaxResults: a.setLen(suggestMaxResults)
|
if a.len > conf.suggestMaxResults: a.setLen(conf.suggestMaxResults)
|
||||||
if not isNil(suggestionResultHook):
|
if not isNil(conf.suggestionResultHook):
|
||||||
for s in a:
|
for s in a:
|
||||||
suggestionResultHook(s)
|
conf.suggestionResultHook(s)
|
||||||
else:
|
else:
|
||||||
for s in a:
|
for s in a:
|
||||||
suggestWriteln($s)
|
conf.suggestWriteln($s)
|
||||||
|
|
||||||
proc filterSym(s: PSym; prefix: PNode; res: var PrefixMatch): bool {.inline.} =
|
proc filterSym(s: PSym; prefix: PNode; res: var PrefixMatch): bool {.inline.} =
|
||||||
proc prefixMatch(s: PSym; n: PNode): PrefixMatch =
|
proc prefixMatch(s: PSym; n: PNode): PrefixMatch =
|
||||||
|
|
@ -340,7 +316,7 @@ proc suggestFieldAccess(c: PContext, n, field: PNode, outputs: var Suggestions)
|
||||||
var typ = n.typ
|
var typ = n.typ
|
||||||
var pm: PrefixMatch
|
var pm: PrefixMatch
|
||||||
when defined(nimsuggest):
|
when defined(nimsuggest):
|
||||||
if n.kind == nkSym and n.sym.kind == skError and suggestVersion == 0:
|
if n.kind == nkSym and n.sym.kind == skError and c.config.suggestVersion == 0:
|
||||||
# consider 'foo.|' where 'foo' is some not imported module.
|
# consider 'foo.|' where 'foo' is some not imported module.
|
||||||
let fullPath = findModule(c.config, n.sym.name.s, toFullPath(c.config, n.info))
|
let fullPath = findModule(c.config, n.sym.name.s, toFullPath(c.config, n.info))
|
||||||
if fullPath.len == 0:
|
if fullPath.len == 0:
|
||||||
|
|
@ -397,17 +373,17 @@ type
|
||||||
TCheckPointResult* = enum
|
TCheckPointResult* = enum
|
||||||
cpNone, cpFuzzy, cpExact
|
cpNone, cpFuzzy, cpExact
|
||||||
|
|
||||||
proc inCheckpoint*(current: TLineInfo): TCheckPointResult =
|
proc inCheckpoint*(current, trackPos: TLineInfo): TCheckPointResult =
|
||||||
if current.fileIndex == gTrackPos.fileIndex:
|
if current.fileIndex == trackPos.fileIndex:
|
||||||
if current.line == gTrackPos.line and
|
if current.line == trackPos.line and
|
||||||
abs(current.col-gTrackPos.col) < 4:
|
abs(current.col-trackPos.col) < 4:
|
||||||
return cpExact
|
return cpExact
|
||||||
if current.line >= gTrackPos.line:
|
if current.line >= trackPos.line:
|
||||||
return cpFuzzy
|
return cpFuzzy
|
||||||
|
|
||||||
proc isTracked*(current: TLineInfo, tokenLen: int): bool =
|
proc isTracked*(current, trackPos: TLineInfo, tokenLen: int): bool =
|
||||||
if current.fileIndex==gTrackPos.fileIndex and current.line==gTrackPos.line:
|
if current.fileIndex==trackPos.fileIndex and current.line==trackPos.line:
|
||||||
let col = gTrackPos.col
|
let col = trackPos.col
|
||||||
if col >= current.col and col <= current.col+tokenLen-1:
|
if col >= current.col and col <= current.col+tokenLen-1:
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
|
@ -425,30 +401,27 @@ when defined(nimsuggest):
|
||||||
if infoB.infoToInt == infoAsInt: return
|
if infoB.infoToInt == infoAsInt: return
|
||||||
s.allUsages.add(info)
|
s.allUsages.add(info)
|
||||||
|
|
||||||
var
|
|
||||||
lastLineInfo*: TLineInfo # XXX global here
|
|
||||||
|
|
||||||
proc findUsages(conf: ConfigRef; info: TLineInfo; s: PSym; usageSym: var PSym) =
|
proc findUsages(conf: ConfigRef; info: TLineInfo; s: PSym; usageSym: var PSym) =
|
||||||
if suggestVersion == 1:
|
if conf.suggestVersion == 1:
|
||||||
if usageSym == nil and isTracked(info, s.name.s.len):
|
if usageSym == nil and isTracked(info, conf.m.trackPos, s.name.s.len):
|
||||||
usageSym = s
|
usageSym = s
|
||||||
suggestResult(symToSuggest(conf, s, isLocal=false, ideUse, info, 100, PrefixMatch.None, false, 0))
|
suggestResult(conf, symToSuggest(conf, s, isLocal=false, ideUse, info, 100, PrefixMatch.None, false, 0))
|
||||||
elif s == usageSym:
|
elif s == usageSym:
|
||||||
if lastLineInfo != info:
|
if conf.lastLineInfo != info:
|
||||||
suggestResult(symToSuggest(conf, s, isLocal=false, ideUse, info, 100, PrefixMatch.None, false, 0))
|
suggestResult(conf, symToSuggest(conf, s, isLocal=false, ideUse, info, 100, PrefixMatch.None, false, 0))
|
||||||
lastLineInfo = info
|
conf.lastLineInfo = info
|
||||||
|
|
||||||
when defined(nimsuggest):
|
when defined(nimsuggest):
|
||||||
proc listUsages*(conf: ConfigRef; s: PSym) =
|
proc listUsages*(conf: ConfigRef; s: PSym) =
|
||||||
#echo "usages ", len(s.allUsages)
|
#echo "usages ", len(s.allUsages)
|
||||||
for info in s.allUsages:
|
for info in s.allUsages:
|
||||||
let x = if info == s.info and info.col == s.info.col: ideDef else: ideUse
|
let x = if info == s.info and info.col == s.info.col: ideDef else: ideUse
|
||||||
suggestResult(symToSuggest(conf, s, isLocal=false, x, info, 100, PrefixMatch.None, false, 0))
|
suggestResult(conf, symToSuggest(conf, s, isLocal=false, x, info, 100, PrefixMatch.None, false, 0))
|
||||||
|
|
||||||
proc findDefinition(conf: ConfigRef; info: TLineInfo; s: PSym) =
|
proc findDefinition(conf: ConfigRef; info: TLineInfo; s: PSym) =
|
||||||
if s.isNil: return
|
if s.isNil: return
|
||||||
if isTracked(info, s.name.s.len):
|
if isTracked(info, conf.m.trackPos, s.name.s.len):
|
||||||
suggestResult(symToSuggest(conf, s, isLocal=false, ideDef, info, 100, PrefixMatch.None, false, 0))
|
suggestResult(conf, symToSuggest(conf, s, isLocal=false, ideDef, info, 100, PrefixMatch.None, false, 0))
|
||||||
suggestQuit()
|
suggestQuit()
|
||||||
|
|
||||||
proc ensureIdx[T](x: var T, y: int) =
|
proc ensureIdx[T](x: var T, y: int) =
|
||||||
|
|
@ -460,7 +433,7 @@ proc ensureSeq[T](x: var seq[T]) =
|
||||||
proc suggestSym*(conf: ConfigRef; info: TLineInfo; s: PSym; usageSym: var PSym; isDecl=true) {.inline.} =
|
proc suggestSym*(conf: ConfigRef; info: TLineInfo; s: PSym; usageSym: var PSym; isDecl=true) {.inline.} =
|
||||||
## misnamed: should be 'symDeclared'
|
## misnamed: should be 'symDeclared'
|
||||||
when defined(nimsuggest):
|
when defined(nimsuggest):
|
||||||
if suggestVersion == 0:
|
if conf.suggestVersion == 0:
|
||||||
if s.allUsages.isNil:
|
if s.allUsages.isNil:
|
||||||
s.allUsages = @[info]
|
s.allUsages = @[info]
|
||||||
else:
|
else:
|
||||||
|
|
@ -471,14 +444,14 @@ proc suggestSym*(conf: ConfigRef; info: TLineInfo; s: PSym; usageSym: var PSym;
|
||||||
elif conf.ideCmd == ideDef:
|
elif conf.ideCmd == ideDef:
|
||||||
findDefinition(conf, info, s)
|
findDefinition(conf, info, s)
|
||||||
elif conf.ideCmd == ideDus and s != nil:
|
elif conf.ideCmd == ideDus and s != nil:
|
||||||
if isTracked(info, s.name.s.len):
|
if isTracked(info, conf.m.trackPos, s.name.s.len):
|
||||||
suggestResult(symToSuggest(conf, s, isLocal=false, ideDef, info, 100, PrefixMatch.None, false, 0))
|
suggestResult(conf, symToSuggest(conf, s, isLocal=false, ideDef, info, 100, PrefixMatch.None, false, 0))
|
||||||
findUsages(conf, info, s, usageSym)
|
findUsages(conf, info, s, usageSym)
|
||||||
elif conf.ideCmd == ideHighlight and info.fileIndex == gTrackPos.fileIndex:
|
elif conf.ideCmd == ideHighlight and info.fileIndex == conf.m.trackPos.fileIndex:
|
||||||
suggestResult(symToSuggest(conf, s, isLocal=false, ideHighlight, info, 100, PrefixMatch.None, false, 0))
|
suggestResult(conf, symToSuggest(conf, s, isLocal=false, ideHighlight, info, 100, PrefixMatch.None, false, 0))
|
||||||
elif conf.ideCmd == ideOutline and info.fileIndex == gTrackPos.fileIndex and
|
elif conf.ideCmd == ideOutline and info.fileIndex == conf.m.trackPos.fileIndex and
|
||||||
isDecl:
|
isDecl:
|
||||||
suggestResult(symToSuggest(conf, s, isLocal=false, ideOutline, info, 100, PrefixMatch.None, false, 0))
|
suggestResult(conf, symToSuggest(conf, s, isLocal=false, ideOutline, info, 100, PrefixMatch.None, false, 0))
|
||||||
|
|
||||||
proc warnAboutDeprecated(conf: ConfigRef; info: TLineInfo; s: PSym) =
|
proc warnAboutDeprecated(conf: ConfigRef; info: TLineInfo; s: PSym) =
|
||||||
if s.kind in routineKinds:
|
if s.kind in routineKinds:
|
||||||
|
|
@ -519,14 +492,14 @@ proc sugExpr(c: PContext, n: PNode, outputs: var Suggestions) =
|
||||||
# of the next line, so we check the 'field' is actually on the same
|
# of the next line, so we check the 'field' is actually on the same
|
||||||
# line as the object to prevent this from happening:
|
# line as the object to prevent this from happening:
|
||||||
let prefix = if n.len == 2 and n[1].info.line == n[0].info.line and
|
let prefix = if n.len == 2 and n[1].info.line == n[0].info.line and
|
||||||
not gTrackPosAttached: n[1] else: nil
|
not c.config.m.trackPosAttached: n[1] else: nil
|
||||||
suggestFieldAccess(c, obj, prefix, outputs)
|
suggestFieldAccess(c, obj, prefix, outputs)
|
||||||
|
|
||||||
#if optIdeDebug in gGlobalOptions:
|
#if optIdeDebug in gGlobalOptions:
|
||||||
# echo "expression ", renderTree(obj), " has type ", typeToString(obj.typ)
|
# echo "expression ", renderTree(obj), " has type ", typeToString(obj.typ)
|
||||||
#writeStackTrace()
|
#writeStackTrace()
|
||||||
else:
|
else:
|
||||||
let prefix = if gTrackPosAttached: nil else: n
|
let prefix = if c.config.m.trackPosAttached: nil else: n
|
||||||
suggestEverything(c, n, prefix, outputs)
|
suggestEverything(c, n, prefix, outputs)
|
||||||
|
|
||||||
proc suggestExprNoCheck*(c: PContext, n: PNode) =
|
proc suggestExprNoCheck*(c: PContext, n: PNode) =
|
||||||
|
|
@ -555,10 +528,10 @@ proc suggestExprNoCheck*(c: PContext, n: PNode) =
|
||||||
suggestQuit()
|
suggestQuit()
|
||||||
|
|
||||||
proc suggestExpr*(c: PContext, n: PNode) =
|
proc suggestExpr*(c: PContext, n: PNode) =
|
||||||
if exactEquals(gTrackPos, n.info): suggestExprNoCheck(c, n)
|
if exactEquals(c.config.m.trackPos, n.info): suggestExprNoCheck(c, n)
|
||||||
|
|
||||||
proc suggestDecl*(c: PContext, n: PNode; s: PSym) =
|
proc suggestDecl*(c: PContext, n: PNode; s: PSym) =
|
||||||
let attached = gTrackPosAttached
|
let attached = c.config.m.trackPosAttached
|
||||||
if attached: inc(c.inTypeContext)
|
if attached: inc(c.inTypeContext)
|
||||||
defer:
|
defer:
|
||||||
if attached: dec(c.inTypeContext)
|
if attached: dec(c.inTypeContext)
|
||||||
|
|
@ -574,7 +547,7 @@ proc suggestEnum*(c: PContext; n: PNode; t: PType) =
|
||||||
if outputs.len > 0: suggestQuit()
|
if outputs.len > 0: suggestQuit()
|
||||||
|
|
||||||
proc suggestSentinel*(c: PContext) =
|
proc suggestSentinel*(c: PContext) =
|
||||||
if c.config.ideCmd != ideSug or c.module.position != gTrackPos.fileIndex.int32: return
|
if c.config.ideCmd != ideSug or c.module.position != c.config.m.trackPos.fileIndex.int32: return
|
||||||
if c.compilesContextId > 0: return
|
if c.compilesContextId > 0: return
|
||||||
inc(c.compilesContextId)
|
inc(c.compilesContextId)
|
||||||
var outputs: Suggestions = @[]
|
var outputs: Suggestions = @[]
|
||||||
|
|
@ -587,7 +560,9 @@ proc suggestSentinel*(c: PContext) =
|
||||||
for it in items(scope.symbols):
|
for it in items(scope.symbols):
|
||||||
var pm: PrefixMatch
|
var pm: PrefixMatch
|
||||||
if filterSymNoOpr(it, nil, pm):
|
if filterSymNoOpr(it, nil, pm):
|
||||||
outputs.add(symToSuggest(c.config, it, isLocal = isLocal, ideSug, newLineInfo(gTrackPos.fileIndex, -1, -1), 0, PrefixMatch.None, false, scopeN))
|
outputs.add(symToSuggest(c.config, it, isLocal = isLocal, ideSug,
|
||||||
|
newLineInfo(c.config.m.trackPos.fileIndex, -1, -1), 0,
|
||||||
|
PrefixMatch.None, false, scopeN))
|
||||||
|
|
||||||
dec(c.compilesContextId)
|
dec(c.compilesContextId)
|
||||||
produceOutput(outputs, c.config)
|
produceOutput(outputs, c.config)
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
strutils, llstream, ast, astalgo, idents, lexer, options, msgs, parser,
|
strutils, llstream, ast, astalgo, idents, lexer, options, msgs, parser,
|
||||||
filters, filter_tmpl, renderer, configuration
|
filters, filter_tmpl, renderer, lineinfos
|
||||||
|
|
||||||
type
|
type
|
||||||
TFilterKind* = enum
|
TFilterKind* = enum
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import
|
||||||
intsets, strutils, options, ast, astalgo, trees, treetab, msgs, os,
|
intsets, strutils, options, ast, astalgo, trees, treetab, msgs, os,
|
||||||
idents, renderer, types, passes, semfold, magicsys, cgmeth, rodread,
|
idents, renderer, types, passes, semfold, magicsys, cgmeth, rodread,
|
||||||
lambdalifting, sempass2, lowerings, lookups, destroyer, liftlocals,
|
lambdalifting, sempass2, lowerings, lookups, destroyer, liftlocals,
|
||||||
modulegraphs
|
modulegraphs, lineinfos
|
||||||
|
|
||||||
type
|
type
|
||||||
PTransNode* = distinct PNode
|
PTransNode* = distinct PNode
|
||||||
|
|
@ -598,7 +598,7 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
|
||||||
idNodeTablePut(newC.mapping, formal, temp)
|
idNodeTablePut(newC.mapping, formal, temp)
|
||||||
|
|
||||||
var body = iter.getBody.copyTree
|
var body = iter.getBody.copyTree
|
||||||
pushInfoContext(n.info)
|
pushInfoContext(c.graph.config, n.info)
|
||||||
# XXX optimize this somehow. But the check "c.inlining" is not correct:
|
# XXX optimize this somehow. But the check "c.inlining" is not correct:
|
||||||
var symMap: TIdTable
|
var symMap: TIdTable
|
||||||
initIdTable symMap
|
initIdTable symMap
|
||||||
|
|
@ -608,7 +608,7 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
|
||||||
add(stmtList, transform(c, body))
|
add(stmtList, transform(c, body))
|
||||||
#findWrongOwners(c, stmtList.pnode)
|
#findWrongOwners(c, stmtList.pnode)
|
||||||
dec(c.inlining)
|
dec(c.inlining)
|
||||||
popInfoContext()
|
popInfoContext(c.graph.config)
|
||||||
popTransCon(c)
|
popTransCon(c)
|
||||||
# echo "transformed: ", stmtList.PNode.renderTree
|
# echo "transformed: ", stmtList.PNode.renderTree
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@
|
||||||
# this module contains routines for accessing and iterating over types
|
# this module contains routines for accessing and iterating over types
|
||||||
|
|
||||||
import
|
import
|
||||||
intsets, ast, astalgo, trees, msgs, strutils, platform, renderer, options
|
intsets, ast, astalgo, trees, msgs, strutils, platform, renderer, options,
|
||||||
|
lineinfos
|
||||||
|
|
||||||
type
|
type
|
||||||
TPreferedDesc* = enum
|
TPreferedDesc* = enum
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import ast except getstr
|
||||||
import
|
import
|
||||||
strutils, astalgo, msgs, vmdef, vmgen, nimsets, types, passes,
|
strutils, astalgo, msgs, vmdef, vmgen, nimsets, types, passes,
|
||||||
parser, vmdeps, idents, trees, renderer, options, transf, parseutils,
|
parser, vmdeps, idents, trees, renderer, options, transf, parseutils,
|
||||||
vmmarshal, gorgeimpl, configuration
|
vmmarshal, gorgeimpl, lineinfos
|
||||||
|
|
||||||
from semfold import leValueConv, ordinalValToString
|
from semfold import leValueConv, ordinalValToString
|
||||||
from evaltempl import evalTemplate
|
from evaltempl import evalTemplate
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
## This module contains the type definitions for the new evaluation engine.
|
## This module contains the type definitions for the new evaluation engine.
|
||||||
## An instruction is 1-3 int32s in memory, it is a register based VM.
|
## An instruction is 1-3 int32s in memory, it is a register based VM.
|
||||||
|
|
||||||
import ast, passes, msgs, idents, intsets, options, modulegraphs
|
import ast, passes, msgs, idents, intsets, options, modulegraphs, lineinfos
|
||||||
|
|
||||||
const
|
const
|
||||||
byteExcess* = 128 # we use excess-K for immediates
|
byteExcess* = 128 # we use excess-K for immediates
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
import ast, types, msgs, os, streams, options, idents
|
import ast, types, msgs, os, streams, options, idents, lineinfos
|
||||||
|
|
||||||
proc opSlurp*(file: string, info: TLineInfo, module: PSym; conf: ConfigRef): string =
|
proc opSlurp*(file: string, info: TLineInfo, module: PSym; conf: ConfigRef): string =
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
strutils, ast, astalgo, types, msgs, renderer, vmdef,
|
strutils, ast, astalgo, types, msgs, renderer, vmdef,
|
||||||
trees, intsets, rodread, magicsys, options, lowerings
|
trees, intsets, rodread, magicsys, options, lowerings, lineinfos
|
||||||
import platform
|
import platform
|
||||||
from os import splitFile
|
from os import splitFile
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
## Implements marshaling for the VM.
|
## Implements marshaling for the VM.
|
||||||
|
|
||||||
import streams, json, intsets, tables, ast, astalgo, idents, types, msgs,
|
import streams, json, intsets, tables, ast, astalgo, idents, types, msgs,
|
||||||
options
|
options, lineinfos
|
||||||
|
|
||||||
proc ptrToInt(x: PNode): int {.inline.} =
|
proc ptrToInt(x: PNode): int {.inline.} =
|
||||||
result = cast[int](x) # don't skip alignment
|
result = cast[int](x) # don't skip alignment
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,8 @@
|
||||||
## * Computing an aliasing relation based on the assignments. This relation
|
## * Computing an aliasing relation based on the assignments. This relation
|
||||||
## is then used to compute the 'writes' and 'escapes' effects.
|
## is then used to compute the 'writes' and 'escapes' effects.
|
||||||
|
|
||||||
import intsets, idents, ast, astalgo, trees, renderer, msgs, types, options
|
import intsets, idents, ast, astalgo, trees, renderer, msgs, types, options,
|
||||||
|
lineinfos
|
||||||
|
|
||||||
const
|
const
|
||||||
debug = false
|
debug = false
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import compiler / [options, commands, modules, sem,
|
||||||
passes, passaux, msgs, nimconf,
|
passes, passaux, msgs, nimconf,
|
||||||
extccomp, condsyms,
|
extccomp, condsyms,
|
||||||
sigmatch, ast, scriptconfig,
|
sigmatch, ast, scriptconfig,
|
||||||
idents, modulegraphs, vm, prefixmatches]
|
idents, modulegraphs, vm, prefixmatches, lineinfos]
|
||||||
|
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
import winlean
|
import winlean
|
||||||
|
|
@ -109,7 +109,7 @@ proc sexp(s: Suggest): SexpNode =
|
||||||
let qp = if s.qualifiedPath.isNil: @[] else: s.qualifiedPath
|
let qp = if s.qualifiedPath.isNil: @[] else: s.qualifiedPath
|
||||||
result = convertSexp([
|
result = convertSexp([
|
||||||
s.section,
|
s.section,
|
||||||
s.symkind,
|
TSymKind s.symkind,
|
||||||
qp.map(newSString),
|
qp.map(newSString),
|
||||||
s.filePath,
|
s.filePath,
|
||||||
s.forth,
|
s.forth,
|
||||||
|
|
@ -141,20 +141,19 @@ proc listEpc(): SexpNode =
|
||||||
methodDesc.add(docstring)
|
methodDesc.add(docstring)
|
||||||
result.add(methodDesc)
|
result.add(methodDesc)
|
||||||
|
|
||||||
proc findNode(n: PNode): PSym =
|
proc findNode(n: PNode; trackPos: TLineInfo): PSym =
|
||||||
#echo "checking node ", n.info
|
#echo "checking node ", n.info
|
||||||
if n.kind == nkSym:
|
if n.kind == nkSym:
|
||||||
if isTracked(n.info, n.sym.name.s.len): return n.sym
|
if isTracked(n.info, trackPos, n.sym.name.s.len): return n.sym
|
||||||
else:
|
else:
|
||||||
for i in 0 ..< safeLen(n):
|
for i in 0 ..< safeLen(n):
|
||||||
let res = n.sons[i].findNode
|
let res = findNode(n[i], trackPos)
|
||||||
if res != nil: return res
|
if res != nil: return res
|
||||||
|
|
||||||
proc symFromInfo(graph: ModuleGraph; gTrackPos: TLineInfo): PSym =
|
proc symFromInfo(graph: ModuleGraph; trackPos: TLineInfo): PSym =
|
||||||
let m = graph.getModule(gTrackPos.fileIndex)
|
let m = graph.getModule(trackPos.fileIndex)
|
||||||
#echo m.isNil, " I knew it ", gTrackPos.fileIndex
|
|
||||||
if m != nil and m.ast != nil:
|
if m != nil and m.ast != nil:
|
||||||
result = m.ast.findNode
|
result = findNode(m.ast, trackPos)
|
||||||
|
|
||||||
proc execute(cmd: IdeCmd, file, dirtyfile: string, line, col: int;
|
proc execute(cmd: IdeCmd, file, dirtyfile: string, line, col: int;
|
||||||
graph: ModuleGraph; cache: IdentCache) =
|
graph: ModuleGraph; cache: IdentCache) =
|
||||||
|
|
@ -163,12 +162,12 @@ proc execute(cmd: IdeCmd, file, dirtyfile: string, line, col: int;
|
||||||
"[" & $line & ":" & $col & "]")
|
"[" & $line & ":" & $col & "]")
|
||||||
conf.ideCmd = cmd
|
conf.ideCmd = cmd
|
||||||
if cmd == ideChk:
|
if cmd == ideChk:
|
||||||
msgs.structuredErrorHook = errorHook
|
conf.structuredErrorHook = errorHook
|
||||||
msgs.writelnHook = myLog
|
conf.writelnHook = myLog
|
||||||
else:
|
else:
|
||||||
msgs.structuredErrorHook = nil
|
conf.structuredErrorHook = nil
|
||||||
msgs.writelnHook = myLog
|
conf.writelnHook = myLog
|
||||||
if cmd == ideUse and suggestVersion != 0:
|
if cmd == ideUse and conf.suggestVersion != 0:
|
||||||
graph.resetAllModules()
|
graph.resetAllModules()
|
||||||
var isKnownFile = true
|
var isKnownFile = true
|
||||||
let dirtyIdx = fileInfoIdx(conf, file, isKnownFile)
|
let dirtyIdx = fileInfoIdx(conf, file, isKnownFile)
|
||||||
|
|
@ -176,14 +175,14 @@ proc execute(cmd: IdeCmd, file, dirtyfile: string, line, col: int;
|
||||||
if dirtyfile.len != 0: msgs.setDirtyFile(conf, dirtyIdx, dirtyfile)
|
if dirtyfile.len != 0: msgs.setDirtyFile(conf, dirtyIdx, dirtyfile)
|
||||||
else: msgs.setDirtyFile(conf, dirtyIdx, nil)
|
else: msgs.setDirtyFile(conf, dirtyIdx, nil)
|
||||||
|
|
||||||
gTrackPos = newLineInfo(dirtyIdx, line, col)
|
conf.m.trackPos = newLineInfo(dirtyIdx, line, col)
|
||||||
gTrackPosAttached = false
|
conf.m.trackPosAttached = false
|
||||||
conf.errorCounter = 0
|
conf.errorCounter = 0
|
||||||
if suggestVersion == 1:
|
if conf.suggestVersion == 1:
|
||||||
graph.usageSym = nil
|
graph.usageSym = nil
|
||||||
if not isKnownFile:
|
if not isKnownFile:
|
||||||
graph.compileProject(cache)
|
graph.compileProject(cache)
|
||||||
if suggestVersion == 0 and conf.ideCmd in {ideUse, ideDus} and
|
if conf.suggestVersion == 0 and conf.ideCmd in {ideUse, ideDus} and
|
||||||
dirtyfile.len == 0:
|
dirtyfile.len == 0:
|
||||||
discard "no need to recompile anything"
|
discard "no need to recompile anything"
|
||||||
else:
|
else:
|
||||||
|
|
@ -193,11 +192,11 @@ proc execute(cmd: IdeCmd, file, dirtyfile: string, line, col: int;
|
||||||
if conf.ideCmd != ideMod:
|
if conf.ideCmd != ideMod:
|
||||||
graph.compileProject(cache, modIdx)
|
graph.compileProject(cache, modIdx)
|
||||||
if conf.ideCmd in {ideUse, ideDus}:
|
if conf.ideCmd in {ideUse, ideDus}:
|
||||||
let u = if suggestVersion != 1: graph.symFromInfo(gTrackPos) else: graph.usageSym
|
let u = if conf.suggestVersion != 1: graph.symFromInfo(conf.m.trackPos) else: graph.usageSym
|
||||||
if u != nil:
|
if u != nil:
|
||||||
listUsages(conf, u)
|
listUsages(conf, u)
|
||||||
else:
|
else:
|
||||||
localError(conf, gTrackPos, "found no symbol at this position " & $gTrackPos)
|
localError(conf, conf.m.trackPos, "found no symbol at this position " & (conf $ conf.m.trackPos))
|
||||||
|
|
||||||
proc executeEpc(cmd: IdeCmd, args: SexpNode;
|
proc executeEpc(cmd: IdeCmd, args: SexpNode;
|
||||||
graph: ModuleGraph; cache: IdentCache) =
|
graph: ModuleGraph; cache: IdentCache) =
|
||||||
|
|
@ -457,16 +456,16 @@ proc mainThread(graph: ModuleGraph; cache: IdentCache) =
|
||||||
else:
|
else:
|
||||||
writelnToChannel(line)
|
writelnToChannel(line)
|
||||||
|
|
||||||
msgs.writelnHook = wrHook
|
conf.writelnHook = wrHook
|
||||||
suggestionResultHook = sugResultHook
|
conf.suggestionResultHook = sugResultHook
|
||||||
graph.doStopCompile = proc (): bool = requests.peek() > 0
|
graph.doStopCompile = proc (): bool = requests.peek() > 0
|
||||||
var idle = 0
|
var idle = 0
|
||||||
var cachedMsgs: CachedMsgs = @[]
|
var cachedMsgs: CachedMsgs = @[]
|
||||||
while true:
|
while true:
|
||||||
let (hasData, req) = requests.tryRecv()
|
let (hasData, req) = requests.tryRecv()
|
||||||
if hasData:
|
if hasData:
|
||||||
msgs.writelnHook = wrHook
|
conf.writelnHook = wrHook
|
||||||
suggestionResultHook = sugResultHook
|
conf.suggestionResultHook = sugResultHook
|
||||||
execCmd(req, graph, cache, cachedMsgs)
|
execCmd(req, graph, cache, cachedMsgs)
|
||||||
idle = 0
|
idle = 0
|
||||||
else:
|
else:
|
||||||
|
|
@ -475,11 +474,11 @@ proc mainThread(graph: ModuleGraph; cache: IdentCache) =
|
||||||
if idle == 20 and gRefresh:
|
if idle == 20 and gRefresh:
|
||||||
# we use some nimsuggest activity to enable a lazy recompile:
|
# we use some nimsuggest activity to enable a lazy recompile:
|
||||||
conf.ideCmd = ideChk
|
conf.ideCmd = ideChk
|
||||||
msgs.writelnHook = proc (s: string) = discard
|
conf.writelnHook = proc (s: string) = discard
|
||||||
cachedMsgs.setLen 0
|
cachedMsgs.setLen 0
|
||||||
msgs.structuredErrorHook = proc (conf: ConfigRef; info: TLineInfo; msg: string; sev: Severity) =
|
conf.structuredErrorHook = proc (conf: ConfigRef; info: TLineInfo; msg: string; sev: Severity) =
|
||||||
cachedMsgs.add(CachedMsg(info: info, msg: msg, sev: sev))
|
cachedMsgs.add(CachedMsg(info: info, msg: msg, sev: sev))
|
||||||
suggestionResultHook = proc (s: Suggest) = discard
|
conf.suggestionResultHook = proc (s: Suggest) = discard
|
||||||
recompileFullProject(graph, cache)
|
recompileFullProject(graph, cache)
|
||||||
|
|
||||||
var
|
var
|
||||||
|
|
@ -502,8 +501,8 @@ proc mainCommand(graph: ModuleGraph; cache: IdentCache) =
|
||||||
# do not stop after the first error:
|
# do not stop after the first error:
|
||||||
conf.errorMax = high(int)
|
conf.errorMax = high(int)
|
||||||
# do not print errors, but log them
|
# do not print errors, but log them
|
||||||
msgs.writelnHook = proc (s: string) = log(s)
|
conf.writelnHook = proc (s: string) = log(s)
|
||||||
msgs.structuredErrorHook = nil
|
conf.structuredErrorHook = nil
|
||||||
|
|
||||||
# compile the project before showing any input so that we already
|
# compile the project before showing any input so that we already
|
||||||
# can answer questions right away:
|
# can answer questions right away:
|
||||||
|
|
@ -555,8 +554,8 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string; conf: ConfigRef) =
|
||||||
gMode = mepc
|
gMode = mepc
|
||||||
conf.verbosity = 0 # Port number gotta be first.
|
conf.verbosity = 0 # Port number gotta be first.
|
||||||
of "debug": incl(conf.globalOptions, optIdeDebug)
|
of "debug": incl(conf.globalOptions, optIdeDebug)
|
||||||
of "v2": suggestVersion = 0
|
of "v2": conf.suggestVersion = 0
|
||||||
of "v1": suggestVersion = 1
|
of "v1": conf.suggestVersion = 1
|
||||||
of "tester":
|
of "tester":
|
||||||
gMode = mstdin
|
gMode = mstdin
|
||||||
gEmitEof = true
|
gEmitEof = true
|
||||||
|
|
@ -568,7 +567,7 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string; conf: ConfigRef) =
|
||||||
else:
|
else:
|
||||||
gRefresh = true
|
gRefresh = true
|
||||||
of "maxresults":
|
of "maxresults":
|
||||||
suggestMaxResults = parseInt(p.val)
|
conf.suggestMaxResults = parseInt(p.val)
|
||||||
else: processSwitch(pass, p, conf)
|
else: processSwitch(pass, p, conf)
|
||||||
of cmdArgument:
|
of cmdArgument:
|
||||||
let a = unixToNativePath(p.key)
|
let a = unixToNativePath(p.key)
|
||||||
|
|
@ -589,7 +588,7 @@ proc handleCmdLine(cache: IdentCache; conf: ConfigRef) =
|
||||||
else:
|
else:
|
||||||
processCmdLine(passCmd1, "", conf)
|
processCmdLine(passCmd1, "", conf)
|
||||||
if gMode != mstdin:
|
if gMode != mstdin:
|
||||||
msgs.writelnHook = proc (msg: string) = discard
|
conf.writelnHook = proc (msg: string) = discard
|
||||||
if conf.projectName != "":
|
if conf.projectName != "":
|
||||||
try:
|
try:
|
||||||
conf.projectFull = canonicalizePath(conf, conf.projectName)
|
conf.projectFull = canonicalizePath(conf, conf.projectName)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue