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
|
||||
|
||||
import
|
||||
msgs, hashes, nversion, options, strutils, std / sha1, ropes, idents,
|
||||
lineinfos, hashes, nversion, options, strutils, std / sha1, ropes, idents,
|
||||
intsets, idgen
|
||||
|
||||
type
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@
|
|||
# the data structures here are used in various places of the compiler.
|
||||
|
||||
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 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 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):
|
||||
# these are for debugging only: They are not really deprecated, but I want
|
||||
# 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
|
||||
# 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
|
||||
var h: Hash = hashNode(obj) and high(t.data) # start with real hash value
|
||||
while t.data[h] != nil:
|
||||
|
|
@ -494,12 +457,12 @@ proc objectSetEnlarge(t: var TObjectSet) =
|
|||
if t.data[i] != nil: objectSetRawInsert(n, t.data[i])
|
||||
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)
|
||||
objectSetRawInsert(t.data, obj)
|
||||
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:
|
||||
var h: Hash = hashNode(obj) and high(t.data)
|
||||
while true:
|
||||
|
|
@ -517,7 +480,7 @@ proc objectSetContainsOrIncl(t: var TObjectSet, obj: RootRef): bool =
|
|||
inc(t.counter)
|
||||
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
|
||||
while t.data[h] != nil:
|
||||
if (t.data[h] == n):
|
||||
|
|
@ -573,7 +536,7 @@ proc strTableEnlarge(t: var TStrTable) =
|
|||
if t.data[i] != nil: strTableRawInsert(n, t.data[i])
|
||||
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)
|
||||
strTableRawInsert(t.data, n)
|
||||
inc(t.counter)
|
||||
|
|
@ -609,7 +572,7 @@ proc strTableIncl*(t: var TStrTable, n: PSym; onConflictKeepOld=false): bool {.d
|
|||
inc(t.counter)
|
||||
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)
|
||||
while true:
|
||||
result = t.data[h]
|
||||
|
|
@ -617,13 +580,13 @@ proc strTableGet(t: TStrTable, name: PIdent): PSym =
|
|||
if result.name.id == name.id: break
|
||||
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 start = h
|
||||
result = tab.data[h]
|
||||
|
|
@ -636,6 +599,12 @@ proc nextIdentIter(ti: var TIdentIter, tab: TStrTable): PSym =
|
|||
result = tab.data[h]
|
||||
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,
|
||||
excluding: IntSet): PSym =
|
||||
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
|
||||
else: result = nextIdentExcluding(ti, tab, excluding)
|
||||
|
||||
proc initTabIter(ti: var TTabIter, tab: TStrTable): PSym =
|
||||
ti.h = 0 # we start by zero ...
|
||||
if tab.counter == 0:
|
||||
result = nil # FIX 1: removed endless loop
|
||||
else:
|
||||
result = nextIter(ti, tab)
|
||||
type
|
||||
TTabIter* = object
|
||||
h: Hash
|
||||
|
||||
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
|
||||
while (ti.h <= high(tab.data)):
|
||||
result = tab.data[ti.h]
|
||||
inc(ti.h) # ... and increment by one always
|
||||
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 =
|
||||
var it: TTabIter
|
||||
var s = initTabIter(it, tab)
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ template getUniqueType*(key: PType): PType = key
|
|||
proc makeSingleLineCString*(s: string): string =
|
||||
result = "\""
|
||||
for c in items(s):
|
||||
result.add(c.toCChar)
|
||||
c.toCChar(result)
|
||||
result.add('\"')
|
||||
|
||||
proc mangle*(name: string): string =
|
||||
|
|
|
|||
|
|
@ -14,12 +14,12 @@ import
|
|||
nversion, nimsets, msgs, std / sha1, bitsets, idents, types,
|
||||
ccgutils, os, ropes, math, passes, rodread, wordrecg, treetab, cgmeth,
|
||||
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.`%`
|
||||
|
||||
from modulegraphs import ModuleGraph
|
||||
from configuration import
|
||||
from lineinfos import
|
||||
warnGcMem, errXMustBeCompileTime, hintDependency, errGenerated, errCannotOpenFile
|
||||
import dynlib
|
||||
|
||||
|
|
@ -949,8 +949,8 @@ proc getFileHeader(conf: ConfigRef; cfile: Cfile): Rope =
|
|||
proc genFilenames(m: BModule): Rope =
|
||||
discard cgsym(m, "dbgRegisterFilename")
|
||||
result = nil
|
||||
for i in 0..<fileInfos.len:
|
||||
result.addf("dbgRegisterFilename($1);$N", [fileInfos[i].projPath.makeCString])
|
||||
for i in 0..<m.config.m.fileInfos.len:
|
||||
result.addf("dbgRegisterFilename($1);$N", [m.config.m.fileInfos[i].projPath.makeCString])
|
||||
|
||||
proc genMainProc(m: BModule) =
|
||||
const
|
||||
|
|
|
|||
|
|
@ -11,9 +11,8 @@
|
|||
|
||||
import
|
||||
ast, astalgo, ropes, passes, options, intsets, platform, sighashes,
|
||||
tables, ndi
|
||||
tables, ndi, lineinfos
|
||||
|
||||
from msgs import TLineInfo
|
||||
from modulegraphs import ModuleGraph
|
||||
|
||||
type
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
import
|
||||
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 =
|
||||
var dest = skipTypes(d, abstractPtrs)
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ bootSwitch(usedNoGC, defined(nogc), "--gc:none")
|
|||
|
||||
import
|
||||
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.
|
||||
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)
|
||||
else: invalidCmdLineOption(conf, pass, orig, info)
|
||||
if state == wHint:
|
||||
let x = findStr(configuration.HintsToStr, id)
|
||||
let x = findStr(lineinfos.HintsToStr, id)
|
||||
if x >= 0: n = TNoteKind(x + ord(hintMin))
|
||||
else: localError(conf, info, "unknown hint: " & id)
|
||||
else:
|
||||
let x = findStr(configuration.WarningsToStr, id)
|
||||
let x = findStr(lineinfos.WarningsToStr, id)
|
||||
if x >= 0: n = TNoteKind(x + ord(warnMin))
|
||||
else: localError(conf, info, "unknown warning: " & id)
|
||||
case substr(arg, i).normalize
|
||||
|
|
@ -324,7 +324,7 @@ proc trackDirty(conf: ConfigRef; arg: string, info: TLineInfo) =
|
|||
if dirtyOriginalIdx.int32 >= 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) =
|
||||
var a = arg.split(',')
|
||||
|
|
@ -334,7 +334,7 @@ proc track(conf: ConfigRef; arg: string, info: TLineInfo) =
|
|||
localError(conf, info, errInvalidNumber % a[1])
|
||||
if parseUtils.parseInt(a[2], column) <= 0:
|
||||
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) =
|
||||
if pass in {passCmd2, passPP}:
|
||||
|
|
|
|||
|
|
@ -1,182 +1,6 @@
|
|||
#
|
||||
#
|
||||
# The Nim Compiler
|
||||
# (c) Copyright 2018 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
## Use the module 'lineinfos' instead!
|
||||
|
||||
## This module contains the rather excessive configuration object that
|
||||
## needs to be passed around to everything so that the compiler becomes
|
||||
## more useful as a library.
|
||||
{.deprecated.}
|
||||
|
||||
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"
|
||||
import lineinfos
|
||||
export lineinfos
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ Remarks: Rule 1.2 is not yet implemented because ``sink`` is currently
|
|||
import
|
||||
intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees,
|
||||
strutils, options, dfa, lowerings, rodread, tables, modulegraphs,
|
||||
configuration
|
||||
lineinfos
|
||||
|
||||
const
|
||||
InterestingSyms = {skVar, skResult, skLet}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
## "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
|
||||
|
||||
import ast, astalgo, types, intsets, tables, msgs, options
|
||||
import ast, astalgo, types, intsets, tables, msgs, options, lineinfos
|
||||
|
||||
type
|
||||
InstrKind* = enum
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import
|
|||
wordrecg, syntaxes, renderer, lexer, packages/docutils/rstast,
|
||||
packages/docutils/rst, packages/docutils/rstgen, times,
|
||||
packages/docutils/highlite, sempass2, json, xmltree, cgi,
|
||||
typesrenderer, astalgo, modulepaths, configuration
|
||||
typesrenderer, astalgo, modulepaths, lineinfos
|
||||
|
||||
type
|
||||
TSections = array[TSymKind, Rope]
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
# semantic checking.
|
||||
|
||||
import
|
||||
os, options, ast, astalgo, msgs, ropes, idents, passes, docgen
|
||||
os, options, ast, astalgo, msgs, ropes, idents, passes, docgen, lineinfos
|
||||
|
||||
from modulegraphs import ModuleGraph
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
import
|
||||
strutils, options, ast, astalgo, msgs, os, idents, wordrecg, renderer,
|
||||
rodread
|
||||
rodread, lineinfos
|
||||
|
||||
type
|
||||
TemplCtx = object
|
||||
|
|
@ -114,7 +114,6 @@ proc evalTemplateArgs(n: PNode, s: PSym; conf: ConfigRef; fromHlo: bool): PNode
|
|||
|
||||
# to prevent endless recursion in template instantiation
|
||||
const evalTemplateLimit* = 1000
|
||||
var evalTemplateCounter* = 0 # XXX remove this global
|
||||
|
||||
proc wrapInComesFrom*(info: TLineInfo; sym: PSym; res: PNode): PNode =
|
||||
when true:
|
||||
|
|
@ -140,8 +139,8 @@ proc wrapInComesFrom*(info: TLineInfo; sym: PSym; res: PNode): PNode =
|
|||
|
||||
proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym;
|
||||
conf: ConfigRef; fromHlo=false): PNode =
|
||||
inc(evalTemplateCounter)
|
||||
if evalTemplateCounter > evalTemplateLimit:
|
||||
inc(conf.evalTemplateCounter)
|
||||
if conf.evalTemplateCounter > evalTemplateLimit:
|
||||
globalError(conf, n.info, errTemplateInstantiationTooNested)
|
||||
result = n
|
||||
|
||||
|
|
@ -170,5 +169,5 @@ proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym;
|
|||
evalTemplateAux(body.sons[i], args, ctx, result)
|
||||
result.flags.incl nfFromTemplate
|
||||
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
|
||||
# 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.
|
||||
|
||||
import
|
||||
ropes, os, strutils, osproc, platform, condsyms, options, msgs,
|
||||
configuration, std / sha1, streams
|
||||
lineinfos, std / sha1, streams
|
||||
|
||||
type
|
||||
TInfoCCProp* = enum # properties of the C compiler:
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
import
|
||||
llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options,
|
||||
renderer, filters
|
||||
renderer, filters, lineinfos
|
||||
|
||||
type
|
||||
TParseState = enum
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@
|
|||
|
||||
## 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) =
|
||||
result[0] = ""
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
## This module implements the 'implies' relation for guards.
|
||||
|
||||
import ast, astalgo, msgs, magicsys, nimsets, trees, types, renderer, idents,
|
||||
saturate, modulegraphs, options, configuration
|
||||
saturate, modulegraphs, options, lineinfos
|
||||
|
||||
const
|
||||
someEq = {mEqI, mEqF64, mEqEnum, mEqCh, mEqB, mEqRef, mEqProc,
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ proc applyPatterns(c: PContext, n: PNode): PNode =
|
|||
if not isNil(x):
|
||||
assert x.kind in {nkStmtList, nkCall}
|
||||
# better be safe than sorry, so check evalTemplateCounter too:
|
||||
inc(evalTemplateCounter)
|
||||
if evalTemplateCounter > evalTemplateLimit:
|
||||
inc(c.config.evalTemplateCounter)
|
||||
if c.config.evalTemplateCounter > evalTemplateLimit:
|
||||
globalError(c.config, n.info, "template instantiation too nested")
|
||||
# deactivate this pattern:
|
||||
c.patterns[i] = nil
|
||||
|
|
@ -54,7 +54,7 @@ proc applyPatterns(c: PContext, n: PNode): PNode =
|
|||
result = flattenStmts(x)
|
||||
else:
|
||||
result = evalPattern(c, x, result)
|
||||
dec(evalTemplateCounter)
|
||||
dec(c.config.evalTemplateCounter)
|
||||
# activate this pattern again:
|
||||
c.patterns[i] = pattern
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
import
|
||||
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 evalFrom*(c: PContext, n: PNode): PNode
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ import
|
|||
ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp, options,
|
||||
nversion, nimsets, msgs, std / sha1, bitsets, idents, types, os, tables,
|
||||
times, ropes, math, passes, ccgutils, wordrecg, renderer, rodread, rodutils,
|
||||
intsets, cgmeth, lowerings, sighashes, configuration
|
||||
intsets, cgmeth, lowerings, sighashes, lineinfos
|
||||
|
||||
from modulegraphs import ModuleGraph
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
import
|
||||
intsets, strutils, options, ast, astalgo, trees, treetab, msgs, os,
|
||||
idents, renderer, types, magicsys, rodread, lowerings, tables,
|
||||
modulegraphs
|
||||
modulegraphs, lineinfos
|
||||
|
||||
discard """
|
||||
The basic approach is that captured vars need to be put on the heap and
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
import
|
||||
hashes, options, msgs, strutils, platform, idents, nimlexbase, llstream,
|
||||
wordrecg, configuration
|
||||
wordrecg, lineinfos
|
||||
|
||||
const
|
||||
MaxLineLength* = 80 # lines longer than this lead to a warning
|
||||
|
|
@ -273,10 +273,10 @@ template tokenBegin(tok, pos) {.dirty.} =
|
|||
template tokenEnd(tok, pos) {.dirty.} =
|
||||
when defined(nimsuggest):
|
||||
let colB = getColNumber(L, pos)+1
|
||||
if L.fileIdx == gTrackPos.fileIndex and gTrackPos.col in colA..colB and
|
||||
L.lineNumber == gTrackPos.line.int and L.config.ideCmd in {ideSug, ideCon}:
|
||||
if L.fileIdx == L.config.m.trackPos.fileIndex and L.config.m.trackPos.col in colA..colB and
|
||||
L.lineNumber == L.config.m.trackPos.line.int and L.config.ideCmd in {ideSug, ideCon}:
|
||||
L.cursor = CursorPosition.InToken
|
||||
gTrackPos.col = colA.int16
|
||||
L.config.m.trackPos.col = colA.int16
|
||||
colA = 0
|
||||
when defined(nimpretty):
|
||||
tok.offsetB = L.offsetBase + pos
|
||||
|
|
@ -284,10 +284,10 @@ template tokenEnd(tok, pos) {.dirty.} =
|
|||
template tokenEndIgnore(tok, pos) =
|
||||
when defined(nimsuggest):
|
||||
let colB = getColNumber(L, pos)
|
||||
if L.fileIdx == gTrackPos.fileIndex and gTrackPos.col in colA..colB and
|
||||
L.lineNumber == gTrackPos.line.int and L.config.ideCmd in {ideSug, ideCon}:
|
||||
gTrackPos.fileIndex = trackPosInvalidFileIdx
|
||||
gTrackPos.line = 0'u16
|
||||
if L.fileIdx == L.config.m.trackPos.fileIndex and L.config.m.trackPos.col in colA..colB and
|
||||
L.lineNumber == L.config.m.trackPos.line.int and L.config.ideCmd in {ideSug, ideCon}:
|
||||
L.config.m.trackPos.fileIndex = trackPosInvalidFileIdx
|
||||
L.config.m.trackPos.line = 0'u16
|
||||
colA = 0
|
||||
when defined(nimpretty):
|
||||
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
|
||||
# the cursor in a string literal or comment:
|
||||
let colB = getColNumber(L, pos)
|
||||
if L.fileIdx == gTrackPos.fileIndex and gTrackPos.col in colA..colB and
|
||||
L.lineNumber == gTrackPos.line.int and L.config.ideCmd in {ideSug, ideCon}:
|
||||
if L.fileIdx == L.config.m.trackPos.fileIndex and L.config.m.trackPos.col in colA..colB and
|
||||
L.lineNumber == L.config.m.trackPos.line.int and L.config.ideCmd in {ideSug, ideCon}:
|
||||
L.cursor = CursorPosition.BeforeToken
|
||||
gTrackPos = L.previousToken
|
||||
gTrackPosAttached = true
|
||||
L.config.m.trackPos = L.previousToken
|
||||
L.config.m.trackPosAttached = true
|
||||
colA = 0
|
||||
when defined(nimpretty):
|
||||
tok.offsetB = L.offsetBase + pos
|
||||
|
|
@ -1121,9 +1121,9 @@ proc rawGetTok*(L: var TLexer, tok: var TToken) =
|
|||
else:
|
||||
tok.tokType = tkParLe
|
||||
when defined(nimsuggest):
|
||||
if L.fileIdx == gTrackPos.fileIndex and tok.col < gTrackPos.col and
|
||||
tok.line == gTrackPos.line.int and L.config.ideCmd == ideCon:
|
||||
gTrackPos.col = tok.col.int16
|
||||
if L.fileIdx == L.config.m.trackPos.fileIndex and tok.col < L.config.m.trackPos.col and
|
||||
tok.line == L.config.m.trackPos.line.int and L.config.ideCmd == ideCon:
|
||||
L.config.m.trackPos.col = tok.col.int16
|
||||
of ')':
|
||||
tok.tokType = tkParRi
|
||||
inc(L.bufpos)
|
||||
|
|
@ -1142,11 +1142,11 @@ proc rawGetTok*(L: var TLexer, tok: var TToken) =
|
|||
inc(L.bufpos)
|
||||
of '.':
|
||||
when defined(nimsuggest):
|
||||
if L.fileIdx == gTrackPos.fileIndex and tok.col+1 == gTrackPos.col and
|
||||
tok.line == gTrackPos.line.int and L.config.ideCmd == ideSug:
|
||||
if L.fileIdx == L.config.m.trackPos.fileIndex and tok.col+1 == L.config.m.trackPos.col and
|
||||
tok.line == L.config.m.trackPos.line.int and L.config.ideCmd == ideSug:
|
||||
tok.tokType = tkDot
|
||||
L.cursor = CursorPosition.InToken
|
||||
gTrackPos.col = tok.col.int16
|
||||
L.config.m.trackPos.col = tok.col.int16
|
||||
inc(L.bufpos)
|
||||
atTokenEnd()
|
||||
return
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
import
|
||||
intsets, strutils, options, ast, astalgo, msgs,
|
||||
idents, renderer, types, lowerings
|
||||
idents, renderer, types, lowerings, lineinfos
|
||||
|
||||
from pragmas import getPragmaVal
|
||||
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
|
||||
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)
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@
|
|||
const
|
||||
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
|
||||
|
||||
proc newDeref*(n: PNode): PNode {.inline.} =
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
import
|
||||
ast, astalgo, hashes, msgs, platform, nversion, times, idents, rodread,
|
||||
modulegraphs
|
||||
modulegraphs, lineinfos
|
||||
|
||||
export createMagic
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import
|
|||
cgen, jsgen, json, nversion,
|
||||
platform, nimconf, importer, passaux, depends, vm, vmdef, types, idgen,
|
||||
docgen2, service, parser, modules, ccgutils, sigmatch, ropes,
|
||||
modulegraphs, tables, rod, configuration
|
||||
modulegraphs, tables, rod, lineinfos
|
||||
|
||||
from magicsys import resetSysTypes
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
## - 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
|
||||
ModuleGraph* = ref object
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
# 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
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
import
|
||||
ast, astalgo, magicsys, std / sha1, rodread, msgs, cgendata, sigmatch, options,
|
||||
idents, os, lexer, idgen, passes, syntaxes, llstream, modulegraphs, rod,
|
||||
configuration
|
||||
lineinfos
|
||||
|
||||
proc resetSystemArtifacts*(g: ModuleGraph) =
|
||||
magicsys.resetSysTypes(g)
|
||||
|
|
@ -118,8 +118,8 @@ proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex;
|
|||
|
||||
proc compileSystemModule*(graph: ModuleGraph; cache: IdentCache) =
|
||||
if graph.systemModule == nil:
|
||||
systemFileIdx = fileInfoIdx(graph.config, graph.config.libpath / "system.nim")
|
||||
discard graph.compileModule(systemFileIdx, cache, {sfSystemModule})
|
||||
graph.config.m.systemFileIdx = fileInfoIdx(graph.config, graph.config.libpath / "system.nim")
|
||||
discard graph.compileModule(graph.config.m.systemFileIdx, cache, {sfSystemModule})
|
||||
|
||||
proc wantMainModule*(conf: ConfigRef) =
|
||||
if conf.projectFull.len == 0:
|
||||
|
|
|
|||
|
|
@ -9,83 +9,28 @@
|
|||
|
||||
import
|
||||
options, strutils, os, tables, ropes, platform, terminal, macros,
|
||||
configuration
|
||||
lineinfos
|
||||
|
||||
#type
|
||||
# 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 =
|
||||
proc toCChar*(c: char; result: var string) =
|
||||
case c
|
||||
of '\0'..'\x1F', '\x7F'..'\xFF': result = '\\' & toOctal(c)
|
||||
of '\'', '\"', '\\', '?': result = '\\' & c
|
||||
else: result = $(c)
|
||||
of '\0'..'\x1F', '\x7F'..'\xFF':
|
||||
result.add '\\'
|
||||
result.add toOctal(c)
|
||||
of '\'', '\"', '\\', '?':
|
||||
result.add '\\'
|
||||
result.add c
|
||||
else:
|
||||
result.add c
|
||||
|
||||
proc makeCString*(s: string): Rope =
|
||||
const
|
||||
MaxLineLength = 64
|
||||
const MaxLineLength = 64
|
||||
result = nil
|
||||
var res = newStringOfCap(int(s.len.toFloat * 1.1) + 1)
|
||||
add(res, "\"")
|
||||
for i in countup(0, len(s) - 1):
|
||||
if (i + 1) mod MaxLineLength == 0:
|
||||
add(res, '\"')
|
||||
add(res, '\L')
|
||||
add(res, '\"')
|
||||
add(res, toCChar(s[i]))
|
||||
add(res, "\"\L\"")
|
||||
toCChar(s[i], res)
|
||||
add(res, '\"')
|
||||
add(result, rope(res))
|
||||
|
||||
|
|
@ -110,8 +55,8 @@ proc newFileInfo(fullPath, projPath: string): TFileInfo =
|
|||
result.fullContent = ""
|
||||
|
||||
when defined(nimpretty):
|
||||
proc fileSection*(fid: FileIndex; a, b: int): string =
|
||||
substr(fileInfos[fid.int].fullContent, a, b)
|
||||
proc fileSection*(conf: ConfigRef; fid: FileIndex; a, b: int): string =
|
||||
substr(conf.m.fileInfos[fid.int].fullContent, a, b)
|
||||
|
||||
proc fileInfoKnown*(conf: ConfigRef; filename: string): bool =
|
||||
var
|
||||
|
|
@ -120,7 +65,7 @@ proc fileInfoKnown*(conf: ConfigRef; filename: string): bool =
|
|||
canon = canonicalizePath(conf, filename)
|
||||
except:
|
||||
canon = filename
|
||||
result = filenameToIndexTbl.hasKey(canon)
|
||||
result = conf.m.filenameToIndexTbl.hasKey(canon)
|
||||
|
||||
proc fileInfoIdx*(conf: ConfigRef; filename: string; isKnownFile: var bool): FileIndex =
|
||||
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
|
||||
pseudoPath = true
|
||||
|
||||
if filenameToIndexTbl.hasKey(canon):
|
||||
result = filenameToIndexTbl[canon]
|
||||
if conf.m.filenameToIndexTbl.hasKey(canon):
|
||||
result = conf.m.filenameToIndexTbl[canon]
|
||||
else:
|
||||
isKnownFile = false
|
||||
result = fileInfos.len.FileIndex
|
||||
fileInfos.add(newFileInfo(canon, if pseudoPath: filename
|
||||
else: shortenDir(conf, canon)))
|
||||
filenameToIndexTbl[canon] = result
|
||||
result = conf.m.fileInfos.len.FileIndex
|
||||
conf.m.fileInfos.add(newFileInfo(canon, if pseudoPath: filename
|
||||
else: shortenDir(conf, canon)))
|
||||
conf.m.filenameToIndexTbl[canon] = result
|
||||
|
||||
proc fileInfoIdx*(conf: ConfigRef; filename: string): FileIndex =
|
||||
var dummy: bool
|
||||
|
|
@ -162,36 +107,19 @@ proc raiseRecoverableError*(msg: string) {.noinline, noreturn.} =
|
|||
|
||||
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 =
|
||||
var totalLen = 0
|
||||
for s in strings: totalLen += s.len
|
||||
result = newStringOfCap totalLen
|
||||
for s in strings: result.add s
|
||||
|
||||
proc suggestWriteln*(s: string) =
|
||||
if eStdOut in errorOutputs:
|
||||
if isNil(writelnHook):
|
||||
proc suggestWriteln*(conf: ConfigRef; s: string) =
|
||||
if eStdOut in conf.m.errorOutputs:
|
||||
if isNil(conf.writelnHook):
|
||||
writeLine(stdout, s)
|
||||
flushFile(stdout)
|
||||
else:
|
||||
writelnHook(s)
|
||||
conf.writelnHook(s)
|
||||
|
||||
proc msgQuit*(x: int8) = quit x
|
||||
proc msgQuit*(x: string) = quit x
|
||||
|
|
@ -212,47 +140,47 @@ const
|
|||
HintTitle = "Hint: "
|
||||
HintColor = fgGreen
|
||||
|
||||
proc getInfoContextLen*(): int = return msgContext.len
|
||||
proc setInfoContextLen*(L: int) = setLen(msgContext, L)
|
||||
proc getInfoContextLen*(conf: ConfigRef): int = return conf.m.msgContext.len
|
||||
proc setInfoContextLen*(conf: ConfigRef; L: int) = setLen(conf.m.msgContext, L)
|
||||
|
||||
proc pushInfoContext*(info: TLineInfo) =
|
||||
msgContext.add(info)
|
||||
proc pushInfoContext*(conf: ConfigRef; info: TLineInfo) =
|
||||
conf.m.msgContext.add(info)
|
||||
|
||||
proc popInfoContext*() =
|
||||
setLen(msgContext, len(msgContext) - 1)
|
||||
proc popInfoContext*(conf: ConfigRef) =
|
||||
setLen(conf.m.msgContext, len(conf.m.msgContext) - 1)
|
||||
|
||||
proc getInfoContext*(index: int): TLineInfo =
|
||||
let L = msgContext.len
|
||||
proc getInfoContext*(conf: ConfigRef; index: int): TLineInfo =
|
||||
let L = conf.m.msgContext.len
|
||||
let i = if index < 0: L + index else: index
|
||||
if i >=% L: result = unknownLineInfo()
|
||||
else: result = msgContext[i]
|
||||
else: result = conf.m.msgContext[i]
|
||||
|
||||
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 =
|
||||
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) =
|
||||
assert fileIdx.int32 >= 0
|
||||
fileInfos[fileIdx.int32].dirtyFile = filename
|
||||
conf.m.fileInfos[fileIdx.int32].dirtyFile = filename
|
||||
|
||||
proc setHash*(conf: ConfigRef; fileIdx: FileIndex; hash: string) =
|
||||
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 =
|
||||
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 =
|
||||
if fileIdx.int32 < 0:
|
||||
result = "???"
|
||||
elif not fileInfos[fileIdx.int32].dirtyFile.isNil:
|
||||
result = fileInfos[fileIdx.int32].dirtyFile
|
||||
elif not conf.m.fileInfos[fileIdx.int32].dirtyFile.isNil:
|
||||
result = conf.m.fileInfos[fileIdx.int32].dirtyFile
|
||||
else:
|
||||
result = fileInfos[fileIdx.int32].fullPath
|
||||
result = conf.m.fileInfos[fileIdx.int32].fullPath
|
||||
|
||||
template toFilename*(conf: ConfigRef; info: TLineInfo): string =
|
||||
toFilename(conf, info.fileIndex)
|
||||
|
|
@ -264,9 +192,9 @@ proc toMsgFilename*(conf: ConfigRef; info: TLineInfo): string =
|
|||
if info.fileIndex.int32 < 0:
|
||||
result = "???"
|
||||
elif optListFullPaths in conf.globalOptions:
|
||||
result = fileInfos[info.fileIndex.int32].fullPath
|
||||
result = conf.m.fileInfos[info.fileIndex.int32].fullPath
|
||||
else:
|
||||
result = fileInfos[info.fileIndex.int32].projPath
|
||||
result = conf.m.fileInfos[info.fileIndex.int32].projPath
|
||||
|
||||
proc toLinenumber*(info: TLineInfo): int {.inline.} =
|
||||
result = int info.line
|
||||
|
|
@ -288,12 +216,6 @@ proc `??`* (conf: ConfigRef; info: TLineInfo, filename: string): bool =
|
|||
# only for debugging purposes
|
||||
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
|
||||
MsgFlag* = enum ## flags altering msgWriteln behavior
|
||||
msgStdout, ## force writing to stdout, even stderr is default
|
||||
|
|
@ -310,14 +232,14 @@ proc msgWriteln*(conf: ConfigRef; s: string, flags: MsgFlags = {}) =
|
|||
## support.
|
||||
#if conf.cmd == cmdIdeTools and optCDebug notin gGlobalOptions: return
|
||||
|
||||
if not isNil(writelnHook) and msgSkipHook notin flags:
|
||||
writelnHook(s)
|
||||
if not isNil(conf.writelnHook) and msgSkipHook notin flags:
|
||||
conf.writelnHook(s)
|
||||
elif optStdout in conf.globalOptions or msgStdout in flags:
|
||||
if eStdOut in errorOutputs:
|
||||
if eStdOut in conf.m.errorOutputs:
|
||||
writeLine(stdout, s)
|
||||
flushFile(stdout)
|
||||
else:
|
||||
if eStdErr in errorOutputs:
|
||||
if eStdErr in conf.m.errorOutputs:
|
||||
writeLine(stderr, s)
|
||||
# On Windows stderr is fully-buffered when piped, regardless of C std.
|
||||
when defined(windows):
|
||||
|
|
@ -348,17 +270,17 @@ macro callStyledWriteLineStderr(args: varargs[typed]): untyped =
|
|||
result.add(arg)
|
||||
|
||||
template callWritelnHook(args: varargs[string, `$`]) =
|
||||
writelnHook concat(args)
|
||||
conf.writelnHook concat(args)
|
||||
|
||||
template styledMsgWriteln*(args: varargs[typed]) =
|
||||
if not isNil(writelnHook):
|
||||
if not isNil(conf.writelnHook):
|
||||
callIgnoringStyle(callWritelnHook, nil, args)
|
||||
elif optStdout in conf.globalOptions:
|
||||
if eStdOut in errorOutputs:
|
||||
if eStdOut in conf.m.errorOutputs:
|
||||
callIgnoringStyle(writeLine, stdout, args)
|
||||
flushFile(stdout)
|
||||
else:
|
||||
if eStdErr in errorOutputs:
|
||||
if eStdErr in conf.m.errorOutputs:
|
||||
if optUseColors in conf.globalOptions:
|
||||
callStyledWriteLineStderr(args)
|
||||
else:
|
||||
|
|
@ -389,7 +311,7 @@ proc log*(s: string) {.procvar.} =
|
|||
|
||||
proc quit(conf: ConfigRef; msg: TMsgKind) =
|
||||
if defined(debug) or msg == errInternal or hintStackTrace in conf.notes:
|
||||
if stackTraceAvailable() and isNil(writelnHook):
|
||||
if stackTraceAvailable() and isNil(conf.writelnHook):
|
||||
writeStackTrace()
|
||||
else:
|
||||
styledMsgWriteln(fgRed, "No stack traceback available\n" &
|
||||
|
|
@ -420,19 +342,19 @@ proc exactEquals*(a, b: TLineInfo): bool =
|
|||
proc writeContext(conf: ConfigRef; lastinfo: TLineInfo) =
|
||||
const instantiationFrom = "template/generic instantiation from here"
|
||||
var info = lastinfo
|
||||
for i in countup(0, len(msgContext) - 1):
|
||||
if msgContext[i] != lastinfo and msgContext[i] != info:
|
||||
if structuredErrorHook != nil:
|
||||
structuredErrorHook(conf, msgContext[i], instantiationFrom,
|
||||
Severity.Error)
|
||||
for i in 0 ..< len(conf.m.msgContext):
|
||||
if conf.m.msgContext[i] != lastinfo and conf.m.msgContext[i] != info:
|
||||
if conf.structuredErrorHook != nil:
|
||||
conf.structuredErrorHook(conf, conf.m.msgContext[i], instantiationFrom,
|
||||
Severity.Error)
|
||||
else:
|
||||
styledMsgWriteln(styleBright,
|
||||
PosFormat % [toMsgFilename(conf, msgContext[i]),
|
||||
coordToStr(msgContext[i].line.int),
|
||||
coordToStr(msgContext[i].col+1)],
|
||||
PosFormat % [toMsgFilename(conf, conf.m.msgContext[i]),
|
||||
coordToStr(conf.m.msgContext[i].line.int),
|
||||
coordToStr(conf.m.msgContext[i].col+1)],
|
||||
resetStyle,
|
||||
instantiationFrom)
|
||||
info = msgContext[i]
|
||||
info = conf.m.msgContext[i]
|
||||
|
||||
proc ignoreMsgBecauseOfIdeTools(conf: ConfigRef; msg: TMsgKind): bool =
|
||||
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)
|
||||
let s = msgKindToString(msg) % args
|
||||
|
||||
if structuredErrorHook != nil:
|
||||
structuredErrorHook(conf, unknownLineInfo(), s & (if kind != nil: KindFormat % kind else: ""), sev)
|
||||
if conf.structuredErrorHook != nil:
|
||||
conf.structuredErrorHook(conf, unknownLineInfo(),
|
||||
s & (if kind != nil: KindFormat % kind else: ""), sev)
|
||||
|
||||
if not ignoreMsgBecauseOfIdeTools(conf, msg):
|
||||
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
|
||||
# in the same file and line are produced:
|
||||
#ignoreMsg = lastError == info and eh != doAbort
|
||||
lastError = info
|
||||
conf.m.lastError = info
|
||||
of warnMin..warnMax:
|
||||
sev = Severity.Warning
|
||||
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)
|
||||
|
||||
if not ignoreMsg:
|
||||
if structuredErrorHook != nil:
|
||||
structuredErrorHook(conf, info, s & (if kind != nil: KindFormat % kind else: ""), sev)
|
||||
if conf.structuredErrorHook != nil:
|
||||
conf.structuredErrorHook(conf, info, s & (if kind != nil: KindFormat % kind else: ""), sev)
|
||||
if not ignoreMsgBecauseOfIdeTools(conf, msg):
|
||||
if kind != nil:
|
||||
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 = "") =
|
||||
# this fixes bug #7080 so that it is at least obvious 'fatal'
|
||||
# was executed.
|
||||
errorOutputs = {eStdOut, eStdErr}
|
||||
conf.m.errorOutputs = {eStdOut, eStdErr}
|
||||
liMessage(conf, info, msg, arg, doAbort)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
liMessage(conf, info, errInternal, errMsg, doAbort)
|
||||
|
||||
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())
|
||||
rawMessage(conf, errInternal, errMsg)
|
||||
|
||||
|
|
@ -596,36 +519,36 @@ template internalAssert*(conf: ConfigRef, e: bool) =
|
|||
if not e: internalError(conf, $instantiationInfo())
|
||||
|
||||
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 =
|
||||
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:
|
||||
for line in lines(toFullPath(conf, i)):
|
||||
addSourceLine conf, i.fileIndex, line.string
|
||||
except IOError:
|
||||
discard
|
||||
assert i.fileIndex.int32 < fileInfos.len
|
||||
assert i.fileIndex.int32 < conf.m.fileInfos.len
|
||||
# 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 =
|
||||
assert i.fileIndex.int32 >= 0
|
||||
if optExcessiveStackTrace in conf.globalOptions:
|
||||
result = fileInfos[i.fileIndex.int32].quotedFullName
|
||||
result = conf.m.fileInfos[i.fileIndex.int32].quotedFullName
|
||||
else:
|
||||
result = fileInfos[i.fileIndex.int32].quotedName
|
||||
result = conf.m.fileInfos[i.fileIndex.int32].quotedName
|
||||
|
||||
proc listWarnings*(conf: ConfigRef) =
|
||||
msgWriteln(conf, "Warnings:")
|
||||
for warn in warnMin..warnMax:
|
||||
msgWriteln(conf, " [$1] $2" % [
|
||||
if warn in conf.notes: "x" else: " ",
|
||||
configuration.WarningsToStr[ord(warn) - ord(warnMin)]
|
||||
lineinfos.WarningsToStr[ord(warn) - ord(warnMin)]
|
||||
])
|
||||
|
||||
proc listHints*(conf: ConfigRef) =
|
||||
|
|
@ -633,5 +556,5 @@ proc listHints*(conf: ConfigRef) =
|
|||
for hint in hintMin..hintMax:
|
||||
msgWriteln(conf, " [$1] $2" % [
|
||||
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
|
||||
commands, lexer, condsyms, options, msgs, nversion, nimconf, ropes,
|
||||
extccomp, strutils, os, osproc, platform, main, parseopt, service,
|
||||
nodejs, scriptconfig, idents, modulegraphs, configuration
|
||||
nodejs, scriptconfig, idents, modulegraphs, lineinfos
|
||||
|
||||
when hasTinyCBackend:
|
||||
import tccgen
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
## Implements some helper procs for Nimble (Nim's package manager) support.
|
||||
|
||||
import parseutils, strutils, strtabs, os, options, msgs, sequtils,
|
||||
configuration
|
||||
lineinfos
|
||||
|
||||
proc addPath*(conf: ConfigRef; path: string, info: TLineInfo) =
|
||||
if not conf.searchPaths.contains(path):
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
import
|
||||
llstream, nversion, commands, os, strutils, msgs, platform, condsyms, lexer,
|
||||
options, idents, wordrecg, strtabs, configuration
|
||||
options, idents, wordrecg, strtabs, lineinfos
|
||||
|
||||
# ---------------- configuration file parser -----------------------------
|
||||
# we use Nim's scanner here to save space and work
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import
|
|||
strutils, os, intsets, strtabs
|
||||
|
||||
import ".." / [options, ast, astalgo, msgs, semdata, ropes, idents,
|
||||
configuration]
|
||||
lineinfos]
|
||||
import prettybase
|
||||
|
||||
type
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
#
|
||||
|
||||
import strutils, lexbase, streams
|
||||
import ".." / [ast, msgs, idents, options]
|
||||
import ".." / [ast, msgs, lineinfos, idents, options]
|
||||
from os import splitFile
|
||||
|
||||
type
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
# this unit handles Nim sets; it implements symbolic sets
|
||||
|
||||
import
|
||||
ast, astalgo, trees, nversion, msgs, platform, bitsets, types, renderer,
|
||||
ast, astalgo, trees, nversion, lineinfos, platform, bitsets, types, renderer,
|
||||
options
|
||||
|
||||
proc inSet*(s: PNode, elem: PNode): bool =
|
||||
|
|
|
|||
|
|
@ -15,6 +15,6 @@ const
|
|||
VersionAsString* = system.NimVersion
|
||||
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
|
||||
## declare this.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@
|
|||
#
|
||||
|
||||
import
|
||||
os, strutils, strtabs, osproc, sets, configuration, platform
|
||||
os, strutils, strtabs, osproc, sets, lineinfos, platform,
|
||||
prefixmatches
|
||||
|
||||
from terminal import isatty
|
||||
|
||||
|
|
@ -135,11 +136,33 @@ type
|
|||
flags*: set[CFileFlag]
|
||||
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
|
||||
target*: Target
|
||||
linesCompiled*: int # all lines that have been compiled
|
||||
options*: TOptions
|
||||
globalOptions*: TGlobalOptions
|
||||
m*: MsgConfig
|
||||
evalTemplateCounter*: int
|
||||
exitcode*: int8
|
||||
cmd*: TCommands # the command
|
||||
selectedGC*: TGCMode # the selected GC
|
||||
|
|
@ -202,6 +225,13 @@ type
|
|||
compileOptions*: string
|
||||
ccompilerpath*: string
|
||||
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}
|
||||
|
||||
|
|
@ -229,6 +259,7 @@ proc newConfigRef*(): ConfigRef =
|
|||
verbosity: 1,
|
||||
options: DefaultOptions,
|
||||
globalOptions: DefaultGlobalOptions,
|
||||
m: initMsgConfig(),
|
||||
evalExpr: "",
|
||||
cppDefines: initSet[string](),
|
||||
headerFile: "", features: {}, foreignPackageNotes: {hintProcessing, warnUnknownMagic,
|
||||
|
|
@ -264,7 +295,8 @@ proc newConfigRef*(): ConfigRef =
|
|||
compileOptions: "",
|
||||
ccompilerpath: "",
|
||||
toCompile: @[],
|
||||
arguments: ""
|
||||
arguments: "",
|
||||
suggestMaxResults: 10_000
|
||||
)
|
||||
setTargetFromSystem(result.target)
|
||||
# enable colors by default on terminals
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ when isMainModule:
|
|||
outp.close
|
||||
|
||||
import
|
||||
llstream, lexer, idents, strutils, ast, astalgo, msgs, options, configuration
|
||||
llstream, lexer, idents, strutils, ast, astalgo, msgs, options, lineinfos
|
||||
|
||||
type
|
||||
TParser* = object # A TParser object represents a file that
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
## implements some little helper passes
|
||||
|
||||
import
|
||||
strutils, ast, astalgo, passes, idents, msgs, options, idgen, configuration
|
||||
strutils, ast, astalgo, passes, idents, msgs, options, idgen, lineinfos
|
||||
|
||||
from modulegraphs import ModuleGraph
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import
|
|||
strutils, options, ast, astalgo, llstream, msgs, platform, os,
|
||||
condsyms, idents, renderer, types, extccomp, math, magicsys, nversion,
|
||||
nimsets, syntaxes, times, rodread, idgen, modulegraphs, reorder, rod,
|
||||
configuration
|
||||
lineinfos
|
||||
|
||||
|
||||
type
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
import
|
||||
os, platform, condsyms, ast, astalgo, idents, semdata, msgs, renderer,
|
||||
wordrecg, ropes, options, strutils, extccomp, math, magicsys, trees,
|
||||
rodread, types, lookups, configuration
|
||||
rodread, types, lookups, lineinfos
|
||||
|
||||
const
|
||||
FirstCallConv* = wNimcall
|
||||
|
|
@ -549,7 +549,7 @@ proc pragmaLine(c: PContext, n: PNode) =
|
|||
localError(c.config, n.info, "tuple expected")
|
||||
else:
|
||||
# sensible default:
|
||||
n.info = getInfoContext(-1)
|
||||
n.info = getInfoContext(c.config, -1)
|
||||
|
||||
proc processPragma(c: PContext, n: PNode, i: int) =
|
||||
let it = n[i]
|
||||
|
|
@ -1047,13 +1047,13 @@ proc implicitPragmas*(c: PContext, sym: PSym, n: PNode,
|
|||
for it in c.optionStack:
|
||||
let o = it.otherPragmas
|
||||
if not o.isNil:
|
||||
pushInfoContext(n.info)
|
||||
pushInfoContext(c.config, n.info)
|
||||
var i = 0
|
||||
while i < o.len():
|
||||
if singlePragma(c, sym, o, i, validPragmas):
|
||||
internalError(c.config, n.info, "implicitPragmas")
|
||||
inc i
|
||||
popInfoContext()
|
||||
popInfoContext(c.config)
|
||||
|
||||
if lfExportLib in sym.loc.flags and sfExportc notin sym.flags:
|
||||
localError(c.config, n.info, ".dynlib requires .exportc")
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ proc prefixMatch*(p, s: string): PrefixMatch =
|
|||
# check for prefix/contains:
|
||||
while i < L:
|
||||
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 jj = 1
|
||||
while ii < L and jj < p.len:
|
||||
|
|
@ -43,10 +43,10 @@ proc prefixMatch*(p, s: string): PrefixMatch =
|
|||
i = 1
|
||||
var j = 1
|
||||
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
|
||||
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
|
||||
else: return PrefixMatch.None
|
||||
inc i
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
# This module implements the renderer of the standard Nim representation.
|
||||
|
||||
import
|
||||
lexer, options, idents, strutils, ast, msgs, configuration
|
||||
lexer, options, idents, strutils, ast, msgs, lineinfos
|
||||
|
||||
type
|
||||
TRenderFlag* = enum
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import
|
||||
intsets, ast, idents, algorithm, renderer, parser, ospaths, strutils,
|
||||
sequtils, msgs, modulegraphs, syntaxes, options, modulepaths, tables,
|
||||
configuration
|
||||
lineinfos
|
||||
|
||||
type
|
||||
DepN = ref object
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
## This module implements the canonalization for the various caching mechanisms.
|
||||
|
||||
import ast, idgen, msgs
|
||||
import ast, idgen, lineinfos, msgs
|
||||
|
||||
when not defined(nimSymbolfiles):
|
||||
template setupModuleCache* = discard
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@
|
|||
import
|
||||
os, options, strutils, nversion, ast, astalgo, msgs, platform, condsyms,
|
||||
ropes, idents, std / sha1, idgen, types, rodutils, memfiles, tables,
|
||||
configuration
|
||||
lineinfos
|
||||
|
||||
type
|
||||
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
|
||||
# be used twice! However, compilation speed does not suffer much from
|
||||
# this, since results are cached.
|
||||
var res = checkDep(systemFileIdx, cache, conf)
|
||||
var res = checkDep(conf.m.systemFileIdx, cache, conf)
|
||||
if res != rrNone: result = rrModDeps
|
||||
for i in countup(0, high(r.modDeps)):
|
||||
res = checkDep(r.modDeps[i], cache, conf)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
import
|
||||
intsets, os, options, strutils, nversion, ast, astalgo, msgs, platform,
|
||||
condsyms, ropes, idents, std / sha1, rodread, passes, idgen,
|
||||
rodutils, modulepaths
|
||||
rodutils, modulepaths, lineinfos
|
||||
|
||||
from modulegraphs import ModuleGraph
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@
|
|||
# To cache them they are inserted in a `cache` array.
|
||||
|
||||
import
|
||||
platform, hashes
|
||||
hashes
|
||||
|
||||
type
|
||||
FormatStr* = string # later we may change it to CString for better
|
||||
|
|
@ -70,8 +70,6 @@ type
|
|||
length*: int
|
||||
data*: string # != nil if a leaf
|
||||
|
||||
RopeSeq* = seq[Rope]
|
||||
|
||||
proc len*(a: Rope): int =
|
||||
## the rope's length
|
||||
if a == nil: result = 0
|
||||
|
|
@ -93,7 +91,7 @@ proc freezeMutableRope*(r: Rope) {.inline.} =
|
|||
r.length = r.data.len
|
||||
|
||||
var
|
||||
cache: array[0..2048*2 - 1, Rope]
|
||||
cache: array[0..2048*2 - 1, Rope] # XXX Global here!
|
||||
|
||||
proc resetRopeCache* =
|
||||
for i in low(cache)..high(cache):
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
import
|
||||
ast, modules, idents, passes, passaux, condsyms,
|
||||
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:
|
||||
from strutils import cmpIgnoreStyle, contains
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import
|
|||
procfind, lookups, rodread, pragmas, passes, semdata, semtypinst, sigmatch,
|
||||
intsets, transf, vmdef, vm, idgen, aliases, cgmeth, lambdalifting,
|
||||
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
|
||||
|
||||
|
|
@ -52,10 +52,10 @@ proc isArrayConstr(n: PNode): bool {.inline.} =
|
|||
result = n.kind == nkBracket and
|
||||
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
|
||||
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
|
||||
|
||||
template semIdeForTemplateOrGeneric(c: PContext; n: PNode;
|
||||
|
|
@ -307,9 +307,9 @@ proc tryConstExpr(c: PContext, n: PNode): PNode =
|
|||
|
||||
let oldErrorCount = c.config.errorCounter
|
||||
let oldErrorMax = c.config.errorMax
|
||||
let oldErrorOutputs = errorOutputs
|
||||
let oldErrorOutputs = c.config.m.errorOutputs
|
||||
|
||||
errorOutputs = {}
|
||||
c.config.m.errorOutputs = {}
|
||||
c.config.errorMax = high(int)
|
||||
|
||||
try:
|
||||
|
|
@ -324,7 +324,7 @@ proc tryConstExpr(c: PContext, n: PNode): PNode =
|
|||
|
||||
c.config.errorCounter = oldErrorCount
|
||||
c.config.errorMax = oldErrorMax
|
||||
errorOutputs = oldErrorOutputs
|
||||
c.config.m.errorOutputs = oldErrorOutputs
|
||||
|
||||
const
|
||||
errConstExprExpected = "constant expression expected"
|
||||
|
|
@ -340,9 +340,9 @@ proc semConstExpr(c: PContext, n: PNode): PNode =
|
|||
result = evalConstExpr(c.module, c.cache, c.graph, e)
|
||||
if result == nil or result.kind == nkEmpty:
|
||||
if e.info != n.info:
|
||||
pushInfoContext(n.info)
|
||||
pushInfoContext(c.config, n.info)
|
||||
localError(c.config, e.info, errConstExprExpected)
|
||||
popInfoContext()
|
||||
popInfoContext(c.config)
|
||||
else:
|
||||
localError(c.config, e.info, errConstExprExpected)
|
||||
# error correction:
|
||||
|
|
@ -380,8 +380,8 @@ proc semAfterMacroCall(c: PContext, call, macroResult: PNode,
|
|||
## coherence, making sure that variables declared with 'let' aren't
|
||||
## reassigned, and binding the unbound identifiers that the macro output
|
||||
## contains.
|
||||
inc(evalTemplateCounter)
|
||||
if evalTemplateCounter > evalTemplateLimit:
|
||||
inc(c.config.evalTemplateCounter)
|
||||
if c.config.evalTemplateCounter > evalTemplateLimit:
|
||||
globalError(c.config, s.info, "template instantiation too nested")
|
||||
c.friendModules.add(s.owner.getModule)
|
||||
|
||||
|
|
@ -420,8 +420,8 @@ proc semAfterMacroCall(c: PContext, call, macroResult: PNode,
|
|||
|
||||
result = semExpr(c, result, flags)
|
||||
result = fitNode(c, retType, result, result.info)
|
||||
#GlobalError(s.info, errInvalidParamKindX, typeToString(s.typ.sons[0]))
|
||||
dec(evalTemplateCounter)
|
||||
#globalError(s.info, errInvalidParamKindX, typeToString(s.typ.sons[0]))
|
||||
dec(c.config.evalTemplateCounter)
|
||||
discard c.friendModules.pop()
|
||||
|
||||
const
|
||||
|
|
@ -429,7 +429,7 @@ const
|
|||
|
||||
proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
|
||||
flags: TExprFlags = {}): PNode =
|
||||
pushInfoContext(nOrig.info)
|
||||
pushInfoContext(c.config, nOrig.info)
|
||||
|
||||
markUsed(c.config, n.info, sym, c.graph.usageSym)
|
||||
styleCheckUse(n.info, sym)
|
||||
|
|
@ -449,7 +449,7 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
|
|||
if efNoSemCheck notin flags:
|
||||
result = semAfterMacroCall(c, n, result, sym, flags)
|
||||
result = wrapInComesFrom(nOrig.info, sym, result)
|
||||
popInfoContext()
|
||||
popInfoContext(c.config)
|
||||
|
||||
proc forceBool(c: PContext, n: PNode): PNode =
|
||||
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:
|
||||
result = semStmtAndGenerateGenerics(c, n)
|
||||
else:
|
||||
let oldContextLen = msgs.getInfoContextLen()
|
||||
let oldContextLen = msgs.getInfoContextLen(c.config)
|
||||
let oldInGenericInst = c.inGenericInst
|
||||
try:
|
||||
result = semStmtAndGenerateGenerics(c, n)
|
||||
except ERecoverableError, ESuggestDone:
|
||||
recoverContext(c)
|
||||
c.inGenericInst = oldInGenericInst
|
||||
msgs.setInfoContextLen(oldContextLen)
|
||||
msgs.setInfoContextLen(c.config, oldContextLen)
|
||||
if getCurrentException() of ESuggestDone:
|
||||
c.suggestionsMade = true
|
||||
result = nil
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) =
|
|||
# Gives a detailed error message; this is separated from semOverloadedCall,
|
||||
# as semOverlodedCall is already pretty slow (and we need this information
|
||||
# only in case of an error).
|
||||
if errorOutputs == {}:
|
||||
if c.config.m.errorOutputs == {}:
|
||||
# fail fast:
|
||||
globalError(c.config, n.info, "type mismatch")
|
||||
if errors.len == 0:
|
||||
|
|
@ -332,7 +332,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
|
|||
internalAssert c.config, result.state == csMatch
|
||||
#writeMatches(result)
|
||||
#writeMatches(alt)
|
||||
if errorOutputs == {}:
|
||||
if c.config.m.errorOutputs == {}:
|
||||
# quick error message for performance of 'compiles' built-in:
|
||||
globalError(c.config, n.info, errGenerated, "ambiguous call")
|
||||
elif c.config.errorCounter == 0:
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import
|
|||
wordrecg,
|
||||
ropes, msgs, platform, os, condsyms, idents, renderer, types, extccomp, math,
|
||||
magicsys, nversion, nimsets, parser, times, passes, rodread, vmdef,
|
||||
modulegraphs, configuration
|
||||
modulegraphs, lineinfos
|
||||
|
||||
type
|
||||
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 =
|
||||
markUsed(c.config, n.info, s, c.graph.usageSym)
|
||||
styleCheckUse(n.info, s)
|
||||
pushInfoContext(n.info)
|
||||
pushInfoContext(c.config, n.info)
|
||||
result = evalTemplate(n, s, getCurrOwner(c), c.config, efFromHlo in 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
|
||||
|
||||
|
|
@ -742,7 +742,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
|||
# This is a proc variable, apply normal overload resolution
|
||||
let m = resolveIndirectCall(c, n, nOrig, t)
|
||||
if m.state != csMatch:
|
||||
if errorOutputs == {}:
|
||||
if c.config.m.errorOutputs == {}:
|
||||
# speed up error generation:
|
||||
globalError(c.config, n.info, "type mismatch")
|
||||
return c.graph.emptyNode
|
||||
|
|
@ -1082,7 +1082,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
|||
when defined(nimsuggest):
|
||||
if c.config.cmd == cmdIdeTools:
|
||||
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})
|
||||
if s != nil:
|
||||
|
|
@ -1783,9 +1783,9 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
|||
openScope(c)
|
||||
let oldOwnerLen = len(c.graph.owners)
|
||||
let oldGenerics = c.generics
|
||||
let oldErrorOutputs = errorOutputs
|
||||
if efExplain notin flags: errorOutputs = {}
|
||||
let oldContextLen = msgs.getInfoContextLen()
|
||||
let oldErrorOutputs = c.config.m.errorOutputs
|
||||
if efExplain notin flags: c.config.m.errorOutputs = {}
|
||||
let oldContextLen = msgs.getInfoContextLen(c.config)
|
||||
|
||||
let oldInGenericContext = c.inGenericContext
|
||||
let oldInUnrolledContext = c.inUnrolledContext
|
||||
|
|
@ -1807,10 +1807,10 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
|||
c.inGenericInst = oldInGenericInst
|
||||
c.inStaticContext = oldInStaticContext
|
||||
c.p = oldProcCon
|
||||
msgs.setInfoContextLen(oldContextLen)
|
||||
msgs.setInfoContextLen(c.config, oldContextLen)
|
||||
setLen(c.graph.owners, oldOwnerLen)
|
||||
c.currentScope = oldScope
|
||||
errorOutputs = oldErrorOutputs
|
||||
c.config.m.errorOutputs = oldErrorOutputs
|
||||
c.config.errorCounter = oldErrorCount
|
||||
c.config.errorMax = oldErrorMax
|
||||
|
||||
|
|
@ -2309,7 +2309,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
|||
# check if it is an expression macro:
|
||||
checkMinSonsLen(n, 1, c.config)
|
||||
#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}
|
||||
var s = qualifiedLookUp(c, n.sons[0], mode)
|
||||
if s != nil:
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
import
|
||||
strutils, options, ast, astalgo, trees, treetab, nimsets, times,
|
||||
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 =
|
||||
case skipTypes(n.typ, abstractVarRange).kind
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ template macroToExpandSym(s): untyped =
|
|||
|
||||
proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym,
|
||||
ctx: var GenericCtx; fromDotExpr=false): PNode =
|
||||
semIdeForTemplateOrGenericCheck(n, ctx.cursorInBody)
|
||||
semIdeForTemplateOrGenericCheck(c.config, n, ctx.cursorInBody)
|
||||
incl(s.flags, sfUsed)
|
||||
case s.kind
|
||||
of skUnknown:
|
||||
|
|
@ -129,7 +129,7 @@ proc newDot(n, b: PNode): PNode =
|
|||
proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags,
|
||||
ctx: var GenericCtx; isMacro: var bool): PNode =
|
||||
assert n.kind == nkDotExpr
|
||||
semIdeForTemplateOrGenericCheck(n, ctx.cursorInBody)
|
||||
semIdeForTemplateOrGenericCheck(c.config, n, ctx.cursorInBody)
|
||||
|
||||
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 conf.cmd == cmdIdeTools: suggestStmt(c, n)
|
||||
semIdeForTemplateOrGenericCheck(n, ctx.cursorInBody)
|
||||
semIdeForTemplateOrGenericCheck(c.config, n, ctx.cursorInBody)
|
||||
|
||||
case n.kind
|
||||
of nkIdent, nkAccQuoted:
|
||||
|
|
|
|||
|
|
@ -159,13 +159,13 @@ proc fixupInstantiatedSymbols(c: PContext, s: PSym) =
|
|||
var oldPrc = c.generics[i].inst.sym
|
||||
pushProcCon(c, oldPrc)
|
||||
pushOwner(c, oldPrc)
|
||||
pushInfoContext(oldPrc.info)
|
||||
pushInfoContext(c.config, oldPrc.info)
|
||||
openScope(c)
|
||||
var n = oldPrc.ast
|
||||
n.sons[bodyPos] = copyTree(s.getBody)
|
||||
instantiateBody(c, n, oldPrc.typ.n, oldPrc, s)
|
||||
closeScope(c)
|
||||
popInfoContext()
|
||||
popInfoContext(c.config)
|
||||
popOwner(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
|
||||
# will need to use openScope, addDecl, etc.
|
||||
#addDecl(c, prc)
|
||||
pushInfoContext(info)
|
||||
pushInfoContext(c.config, info)
|
||||
var typeMap = initLayeredTypeMap(pt)
|
||||
var cl = initTypeVars(c, addr(typeMap), info, nil)
|
||||
var result = instCopyType(cl, prc.typ)
|
||||
|
|
@ -278,7 +278,7 @@ proc instantiateProcType(c: PContext, pt: TIdTable,
|
|||
skipIntLiteralParams(result)
|
||||
|
||||
prc.typ = result
|
||||
popInfoContext()
|
||||
popInfoContext(c.config)
|
||||
|
||||
proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
||||
info: TLineInfo): PSym =
|
||||
|
|
@ -309,7 +309,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
|||
let gp = n.sons[genericParamsPos]
|
||||
internalAssert c.config, gp.kind != nkEmpty
|
||||
n.sons[namePos] = newSymNode(result)
|
||||
pushInfoContext(info)
|
||||
pushInfoContext(c.config, info)
|
||||
var entry = TInstantiation.new
|
||||
entry.sym = result
|
||||
# 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:
|
||||
result = oldPrc
|
||||
popProcCon(c)
|
||||
popInfoContext()
|
||||
popInfoContext(c.config)
|
||||
closeScope(c) # close scope for parameters
|
||||
popOwner(c)
|
||||
c.currentScope = oldScope
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ proc semInstantiationInfo(c: PContext, n: PNode): PNode =
|
|||
result = newNodeIT(nkTupleConstr, n.info, n.typ)
|
||||
let idx = expectIntLit(c, n.sons[1])
|
||||
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))
|
||||
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))
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
import
|
||||
intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees,
|
||||
wordrecg, strutils, options, guards, writetracking, configuration,
|
||||
wordrecg, strutils, options, guards, writetracking, lineinfos,
|
||||
modulegraphs
|
||||
|
||||
when defined(useDfa):
|
||||
|
|
@ -859,9 +859,9 @@ proc checkRaisesSpec(g: ModuleGraph; spec, real: PNode, msg: string, hints: bool
|
|||
used.incl(s)
|
||||
break search
|
||||
# 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))
|
||||
popInfoContext()
|
||||
popInfoContext(g.config)
|
||||
# hint about unnecessarily listed exception types:
|
||||
if hints:
|
||||
for s in 0 ..< spec.len:
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ proc semWhile(c: PContext, n: PNode): PNode =
|
|||
result.typ = c.enforceVoidContext
|
||||
|
||||
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):
|
||||
result = sonsLen(t2.n)
|
||||
else:
|
||||
|
|
@ -201,7 +201,7 @@ proc semCase(c: PContext, n: PNode): PNode =
|
|||
for i in countup(1, sonsLen(n) - 1):
|
||||
var x = n.sons[i]
|
||||
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)
|
||||
case x.kind
|
||||
of nkOfBranch:
|
||||
|
|
@ -1396,14 +1396,14 @@ proc semOverride(c: PContext, s: PSym, n: PNode) =
|
|||
localError(c.config, n.info, errGenerated,
|
||||
"'destroy' or 'deepCopy' expected for 'override'")
|
||||
|
||||
proc cursorInProcAux(n: PNode): bool =
|
||||
if inCheckpoint(n.info) != cpNone: return true
|
||||
proc cursorInProcAux(conf: ConfigRef; n: PNode): bool =
|
||||
if inCheckpoint(n.info, conf.m.trackPos) != cpNone: return true
|
||||
for i in 0..<n.safeLen:
|
||||
if cursorInProcAux(n[i]): return true
|
||||
if cursorInProcAux(conf, n[i]): return true
|
||||
|
||||
proc cursorInProc(n: PNode): bool =
|
||||
if n.info.fileIndex == gTrackPos.fileIndex:
|
||||
result = cursorInProcAux(n)
|
||||
proc cursorInProc(conf: ConfigRef; n: PNode): bool =
|
||||
if n.info.fileIndex == conf.m.trackPos.fileIndex:
|
||||
result = cursorInProcAux(conf, n)
|
||||
|
||||
type
|
||||
TProcCompilationSteps = enum
|
||||
|
|
@ -1583,7 +1583,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
|||
# only used for overload resolution (there is no instantiation of
|
||||
# the symbol, so we must process the body now)
|
||||
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"
|
||||
if s.kind == skMethod: semMethodPrototype(c, s, n)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -305,7 +305,7 @@ proc semTemplBodySons(c: var TemplCtx, n: PNode): PNode =
|
|||
|
||||
proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
|
||||
result = n
|
||||
semIdeForTemplateOrGenericCheck(n, c.cursorInBody)
|
||||
semIdeForTemplateOrGenericCheck(c.c.config, n, c.cursorInBody)
|
||||
case n.kind
|
||||
of nkIdent:
|
||||
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 =
|
||||
result = n
|
||||
semIdeForTemplateOrGenericCheck(n, c.cursorInBody)
|
||||
semIdeForTemplateOrGenericCheck(c.c.config, n, c.cursorInBody)
|
||||
case n.kind
|
||||
of nkIdent:
|
||||
let s = qualifiedLookUp(c.c, n, {})
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@
|
|||
|
||||
# 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
|
||||
tfInstClearedFlags = {tfHasMeta, tfUnresolved}
|
||||
|
|
@ -568,35 +569,35 @@ proc replaceTypesInBody*(p: PContext, pt: TIdTable, n: PNode;
|
|||
var typeMap = initLayeredTypeMap(pt)
|
||||
var cl = initTypeVars(p, addr(typeMap), n.info, owner)
|
||||
cl.allowMetaTypes = allowMetaTypes
|
||||
pushInfoContext(n.info)
|
||||
pushInfoContext(p.config, n.info)
|
||||
result = replaceTypeVarsN(cl, n)
|
||||
popInfoContext()
|
||||
popInfoContext(p.config)
|
||||
|
||||
proc replaceTypesForLambda*(p: PContext, pt: TIdTable, n: PNode;
|
||||
original, new: PSym): PNode =
|
||||
var typeMap = initLayeredTypeMap(pt)
|
||||
var cl = initTypeVars(p, addr(typeMap), n.info, original)
|
||||
idTablePut(cl.symMap, original, new)
|
||||
pushInfoContext(n.info)
|
||||
pushInfoContext(p.config, n.info)
|
||||
result = replaceTypeVarsN(cl, n)
|
||||
popInfoContext()
|
||||
popInfoContext(p.config)
|
||||
|
||||
proc generateTypeInstance*(p: PContext, pt: TIdTable, info: TLineInfo,
|
||||
t: PType): PType =
|
||||
var typeMap = initLayeredTypeMap(pt)
|
||||
var cl = initTypeVars(p, addr(typeMap), info, nil)
|
||||
pushInfoContext(info)
|
||||
pushInfoContext(p.config, info)
|
||||
result = replaceTypeVarsT(cl, t)
|
||||
popInfoContext()
|
||||
popInfoContext(p.config)
|
||||
|
||||
proc prepareMetatypeForSigmatch*(p: PContext, pt: TIdTable, info: TLineInfo,
|
||||
t: PType): PType =
|
||||
var typeMap = initLayeredTypeMap(pt)
|
||||
var cl = initTypeVars(p, addr(typeMap), info, nil)
|
||||
cl.allowMetaTypes = true
|
||||
pushInfoContext(info)
|
||||
pushInfoContext(p.config, info)
|
||||
result = replaceTypeVarsT(cl, t)
|
||||
popInfoContext()
|
||||
popInfoContext(p.config)
|
||||
|
||||
template generateTypeInstance*(p: PContext, pt: TIdTable, arg: PNode,
|
||||
t: PType): untyped =
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
import
|
||||
times, commands, options, msgs, nimconf,
|
||||
extccomp, strutils, os, platform, parseopt, idents, configuration
|
||||
extccomp, strutils, os, platform, parseopt, idents, lineinfos
|
||||
|
||||
when useCaas:
|
||||
import net
|
||||
|
|
@ -71,7 +71,7 @@ proc serve*(cache: IdentCache; action: proc (cache: IdentCache){.nimcall.}; conf
|
|||
var inp = "".TaintedString
|
||||
server.listen()
|
||||
var stdoutSocket = newSocket()
|
||||
msgs.writelnHook = proc (line: string) =
|
||||
config.writelnHook = proc (line: string) =
|
||||
stdoutSocket.send(line & "\c\L")
|
||||
|
||||
while true:
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
import
|
||||
intsets, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst,
|
||||
magicsys, condsyms, idents, lexer, options, parampatterns, strutils, trees,
|
||||
nimfix.pretty
|
||||
nimfix / pretty, lineinfos
|
||||
|
||||
when not defined(noDocgen):
|
||||
import docgen
|
||||
|
|
@ -722,7 +722,7 @@ proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType =
|
|||
addDecl(c, param)
|
||||
|
||||
var
|
||||
oldWriteHook: type(writelnHook)
|
||||
oldWriteHook: type(m.c.config.writelnHook)
|
||||
diagnostics: seq[string]
|
||||
errorPrefix: string
|
||||
flags: TExprFlags = {}
|
||||
|
|
@ -730,12 +730,12 @@ proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType =
|
|||
sfExplain in typeClass.sym.flags
|
||||
|
||||
if collectDiagnostics:
|
||||
oldWriteHook = writelnHook
|
||||
oldWriteHook = m.c.config.writelnHook
|
||||
# XXX: we can't write to m.diagnostics directly, because
|
||||
# Nim doesn't support capturing var params in closures
|
||||
diagnostics = @[]
|
||||
flags = {efExplain}
|
||||
writelnHook = proc (s: string) =
|
||||
m.c.config.writelnHook = proc (s: string) =
|
||||
if errorPrefix == nil: errorPrefix = typeClass.sym.name.s & ":"
|
||||
let msg = s.replace("Error:", errorPrefix)
|
||||
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)
|
||||
|
||||
if collectDiagnostics:
|
||||
writelnHook = oldWriteHook
|
||||
m.c.config.writelnHook = oldWriteHook
|
||||
for msg in diagnostics:
|
||||
m.diagnostics.safeAdd msg
|
||||
m.diagnosticsEnabled = true
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
# included from sigmatch.nim
|
||||
|
||||
import algorithm, prefixmatches, configuration
|
||||
import algorithm, prefixmatches, lineinfos
|
||||
from wordrecg import wDeprecated
|
||||
|
||||
when defined(nimsuggest):
|
||||
|
|
@ -41,31 +41,6 @@ when defined(nimsuggest):
|
|||
const
|
||||
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 origModuleName(m: PSym): string = m.name.s
|
||||
|
|
@ -104,7 +79,7 @@ proc cmpSuggestions(a, b: Suggest): int =
|
|||
cf globalUsages
|
||||
# if all is equal, sort alphabetically for deterministic output,
|
||||
# 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;
|
||||
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.contextFits = inTypeContext == (s.kind in {skType, skGenericParam})
|
||||
result.scope = scope
|
||||
result.name = s.name
|
||||
result.name = addr s.name.s
|
||||
when defined(nimsuggest):
|
||||
result.globalUsages = s.allUsages.len
|
||||
var c = 0
|
||||
for u in s.allUsages:
|
||||
if u.fileIndex == info.fileIndex: inc c
|
||||
result.localUsages = c
|
||||
result.symkind = s.kind
|
||||
result.symkind = byte s.kind
|
||||
if optIdeTerse notin conf.globalOptions:
|
||||
result.qualifiedPath = @[]
|
||||
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.line = toLinenumber(infox)
|
||||
result.column = toColumn(infox)
|
||||
result.version = conf.suggestVersion
|
||||
|
||||
proc `$`*(suggest: Suggest): string =
|
||||
result = $suggest.section
|
||||
result.add(sep)
|
||||
if suggest.section == ideHighlight:
|
||||
if suggest.symkind == skVar and suggest.isGlobal:
|
||||
if suggest.symkind.TSymKind == skVar and suggest.isGlobal:
|
||||
result.add("skGlobalVar")
|
||||
elif suggest.symkind == skLet and suggest.isGlobal:
|
||||
elif suggest.symkind.TSymKind == skLet and suggest.isGlobal:
|
||||
result.add("skGlobalLet")
|
||||
else:
|
||||
result.add($suggest.symkind)
|
||||
result.add($suggest.symkind.TSymKind)
|
||||
result.add(sep)
|
||||
result.add($suggest.line)
|
||||
result.add(sep)
|
||||
|
|
@ -164,9 +140,9 @@ proc `$`*(suggest: Suggest): string =
|
|||
result.add(sep)
|
||||
result.add($suggest.tokenLen)
|
||||
else:
|
||||
result.add($suggest.symkind)
|
||||
result.add($suggest.symkind.TSymKind)
|
||||
result.add(sep)
|
||||
if suggest.qualifiedPath != nil:
|
||||
if suggest.qualifiedPath.len != 0:
|
||||
result.add(suggest.qualifiedPath.join("."))
|
||||
result.add(sep)
|
||||
result.add(suggest.forth)
|
||||
|
|
@ -179,18 +155,18 @@ proc `$`*(suggest: Suggest): string =
|
|||
result.add(sep)
|
||||
when not defined(noDocgen):
|
||||
result.add(suggest.doc.escape)
|
||||
if suggestVersion == 0:
|
||||
if suggest.version == 0:
|
||||
result.add(sep)
|
||||
result.add($suggest.quality)
|
||||
if suggest.section == ideSug:
|
||||
result.add(sep)
|
||||
result.add($suggest.prefix)
|
||||
|
||||
proc suggestResult(s: Suggest) =
|
||||
if not isNil(suggestionResultHook):
|
||||
suggestionResultHook(s)
|
||||
proc suggestResult(conf: ConfigRef; s: Suggest) =
|
||||
if not isNil(conf.suggestionResultHook):
|
||||
conf.suggestionResultHook(s)
|
||||
else:
|
||||
suggestWriteln($s)
|
||||
conf.suggestWriteln($s)
|
||||
|
||||
proc produceOutput(a: var Suggestions; conf: ConfigRef) =
|
||||
if conf.ideCmd in {ideSug, ideCon}:
|
||||
|
|
@ -198,13 +174,13 @@ proc produceOutput(a: var Suggestions; conf: ConfigRef) =
|
|||
when defined(debug):
|
||||
# debug code
|
||||
writeStackTrace()
|
||||
if a.len > suggestMaxResults: a.setLen(suggestMaxResults)
|
||||
if not isNil(suggestionResultHook):
|
||||
if a.len > conf.suggestMaxResults: a.setLen(conf.suggestMaxResults)
|
||||
if not isNil(conf.suggestionResultHook):
|
||||
for s in a:
|
||||
suggestionResultHook(s)
|
||||
conf.suggestionResultHook(s)
|
||||
else:
|
||||
for s in a:
|
||||
suggestWriteln($s)
|
||||
conf.suggestWriteln($s)
|
||||
|
||||
proc filterSym(s: PSym; prefix: PNode; res: var PrefixMatch): bool {.inline.} =
|
||||
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 pm: PrefixMatch
|
||||
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.
|
||||
let fullPath = findModule(c.config, n.sym.name.s, toFullPath(c.config, n.info))
|
||||
if fullPath.len == 0:
|
||||
|
|
@ -397,17 +373,17 @@ type
|
|||
TCheckPointResult* = enum
|
||||
cpNone, cpFuzzy, cpExact
|
||||
|
||||
proc inCheckpoint*(current: TLineInfo): TCheckPointResult =
|
||||
if current.fileIndex == gTrackPos.fileIndex:
|
||||
if current.line == gTrackPos.line and
|
||||
abs(current.col-gTrackPos.col) < 4:
|
||||
proc inCheckpoint*(current, trackPos: TLineInfo): TCheckPointResult =
|
||||
if current.fileIndex == trackPos.fileIndex:
|
||||
if current.line == trackPos.line and
|
||||
abs(current.col-trackPos.col) < 4:
|
||||
return cpExact
|
||||
if current.line >= gTrackPos.line:
|
||||
if current.line >= trackPos.line:
|
||||
return cpFuzzy
|
||||
|
||||
proc isTracked*(current: TLineInfo, tokenLen: int): bool =
|
||||
if current.fileIndex==gTrackPos.fileIndex and current.line==gTrackPos.line:
|
||||
let col = gTrackPos.col
|
||||
proc isTracked*(current, trackPos: TLineInfo, tokenLen: int): bool =
|
||||
if current.fileIndex==trackPos.fileIndex and current.line==trackPos.line:
|
||||
let col = trackPos.col
|
||||
if col >= current.col and col <= current.col+tokenLen-1:
|
||||
return true
|
||||
|
||||
|
|
@ -425,30 +401,27 @@ when defined(nimsuggest):
|
|||
if infoB.infoToInt == infoAsInt: return
|
||||
s.allUsages.add(info)
|
||||
|
||||
var
|
||||
lastLineInfo*: TLineInfo # XXX global here
|
||||
|
||||
proc findUsages(conf: ConfigRef; info: TLineInfo; s: PSym; usageSym: var PSym) =
|
||||
if suggestVersion == 1:
|
||||
if usageSym == nil and isTracked(info, s.name.s.len):
|
||||
if conf.suggestVersion == 1:
|
||||
if usageSym == nil and isTracked(info, conf.m.trackPos, s.name.s.len):
|
||||
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:
|
||||
if lastLineInfo != info:
|
||||
suggestResult(symToSuggest(conf, s, isLocal=false, ideUse, info, 100, PrefixMatch.None, false, 0))
|
||||
lastLineInfo = info
|
||||
if conf.lastLineInfo != info:
|
||||
suggestResult(conf, symToSuggest(conf, s, isLocal=false, ideUse, info, 100, PrefixMatch.None, false, 0))
|
||||
conf.lastLineInfo = info
|
||||
|
||||
when defined(nimsuggest):
|
||||
proc listUsages*(conf: ConfigRef; s: PSym) =
|
||||
#echo "usages ", len(s.allUsages)
|
||||
for info in s.allUsages:
|
||||
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) =
|
||||
if s.isNil: return
|
||||
if isTracked(info, s.name.s.len):
|
||||
suggestResult(symToSuggest(conf, s, isLocal=false, ideDef, info, 100, PrefixMatch.None, false, 0))
|
||||
if isTracked(info, conf.m.trackPos, s.name.s.len):
|
||||
suggestResult(conf, symToSuggest(conf, s, isLocal=false, ideDef, info, 100, PrefixMatch.None, false, 0))
|
||||
suggestQuit()
|
||||
|
||||
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.} =
|
||||
## misnamed: should be 'symDeclared'
|
||||
when defined(nimsuggest):
|
||||
if suggestVersion == 0:
|
||||
if conf.suggestVersion == 0:
|
||||
if s.allUsages.isNil:
|
||||
s.allUsages = @[info]
|
||||
else:
|
||||
|
|
@ -471,14 +444,14 @@ proc suggestSym*(conf: ConfigRef; info: TLineInfo; s: PSym; usageSym: var PSym;
|
|||
elif conf.ideCmd == ideDef:
|
||||
findDefinition(conf, info, s)
|
||||
elif conf.ideCmd == ideDus and s != nil:
|
||||
if isTracked(info, s.name.s.len):
|
||||
suggestResult(symToSuggest(conf, s, isLocal=false, ideDef, info, 100, PrefixMatch.None, false, 0))
|
||||
if isTracked(info, conf.m.trackPos, s.name.s.len):
|
||||
suggestResult(conf, symToSuggest(conf, s, isLocal=false, ideDef, info, 100, PrefixMatch.None, false, 0))
|
||||
findUsages(conf, info, s, usageSym)
|
||||
elif conf.ideCmd == ideHighlight and info.fileIndex == gTrackPos.fileIndex:
|
||||
suggestResult(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 == ideHighlight and info.fileIndex == conf.m.trackPos.fileIndex:
|
||||
suggestResult(conf, symToSuggest(conf, s, isLocal=false, ideHighlight, info, 100, PrefixMatch.None, false, 0))
|
||||
elif conf.ideCmd == ideOutline and info.fileIndex == conf.m.trackPos.fileIndex and
|
||||
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) =
|
||||
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
|
||||
# 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
|
||||
not gTrackPosAttached: n[1] else: nil
|
||||
not c.config.m.trackPosAttached: n[1] else: nil
|
||||
suggestFieldAccess(c, obj, prefix, outputs)
|
||||
|
||||
#if optIdeDebug in gGlobalOptions:
|
||||
# echo "expression ", renderTree(obj), " has type ", typeToString(obj.typ)
|
||||
#writeStackTrace()
|
||||
else:
|
||||
let prefix = if gTrackPosAttached: nil else: n
|
||||
let prefix = if c.config.m.trackPosAttached: nil else: n
|
||||
suggestEverything(c, n, prefix, outputs)
|
||||
|
||||
proc suggestExprNoCheck*(c: PContext, n: PNode) =
|
||||
|
|
@ -555,10 +528,10 @@ proc suggestExprNoCheck*(c: PContext, n: PNode) =
|
|||
suggestQuit()
|
||||
|
||||
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) =
|
||||
let attached = gTrackPosAttached
|
||||
let attached = c.config.m.trackPosAttached
|
||||
if attached: inc(c.inTypeContext)
|
||||
defer:
|
||||
if attached: dec(c.inTypeContext)
|
||||
|
|
@ -574,7 +547,7 @@ proc suggestEnum*(c: PContext; n: PNode; t: PType) =
|
|||
if outputs.len > 0: suggestQuit()
|
||||
|
||||
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
|
||||
inc(c.compilesContextId)
|
||||
var outputs: Suggestions = @[]
|
||||
|
|
@ -587,7 +560,9 @@ proc suggestSentinel*(c: PContext) =
|
|||
for it in items(scope.symbols):
|
||||
var pm: PrefixMatch
|
||||
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)
|
||||
produceOutput(outputs, c.config)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
import
|
||||
strutils, llstream, ast, astalgo, idents, lexer, options, msgs, parser,
|
||||
filters, filter_tmpl, renderer, configuration
|
||||
filters, filter_tmpl, renderer, lineinfos
|
||||
|
||||
type
|
||||
TFilterKind* = enum
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import
|
|||
intsets, strutils, options, ast, astalgo, trees, treetab, msgs, os,
|
||||
idents, renderer, types, passes, semfold, magicsys, cgmeth, rodread,
|
||||
lambdalifting, sempass2, lowerings, lookups, destroyer, liftlocals,
|
||||
modulegraphs
|
||||
modulegraphs, lineinfos
|
||||
|
||||
type
|
||||
PTransNode* = distinct PNode
|
||||
|
|
@ -598,7 +598,7 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
|
|||
idNodeTablePut(newC.mapping, formal, temp)
|
||||
|
||||
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:
|
||||
var symMap: TIdTable
|
||||
initIdTable symMap
|
||||
|
|
@ -608,7 +608,7 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
|
|||
add(stmtList, transform(c, body))
|
||||
#findWrongOwners(c, stmtList.pnode)
|
||||
dec(c.inlining)
|
||||
popInfoContext()
|
||||
popInfoContext(c.graph.config)
|
||||
popTransCon(c)
|
||||
# echo "transformed: ", stmtList.PNode.renderTree
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@
|
|||
# this module contains routines for accessing and iterating over types
|
||||
|
||||
import
|
||||
intsets, ast, astalgo, trees, msgs, strutils, platform, renderer, options
|
||||
intsets, ast, astalgo, trees, msgs, strutils, platform, renderer, options,
|
||||
lineinfos
|
||||
|
||||
type
|
||||
TPreferedDesc* = enum
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import ast except getstr
|
|||
import
|
||||
strutils, astalgo, msgs, vmdef, vmgen, nimsets, types, passes,
|
||||
parser, vmdeps, idents, trees, renderer, options, transf, parseutils,
|
||||
vmmarshal, gorgeimpl, configuration
|
||||
vmmarshal, gorgeimpl, lineinfos
|
||||
|
||||
from semfold import leValueConv, ordinalValToString
|
||||
from evaltempl import evalTemplate
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
## 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.
|
||||
|
||||
import ast, passes, msgs, idents, intsets, options, modulegraphs
|
||||
import ast, passes, msgs, idents, intsets, options, modulegraphs, lineinfos
|
||||
|
||||
const
|
||||
byteExcess* = 128 # we use excess-K for immediates
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
# 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 =
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
import
|
||||
strutils, ast, astalgo, types, msgs, renderer, vmdef,
|
||||
trees, intsets, rodread, magicsys, options, lowerings
|
||||
trees, intsets, rodread, magicsys, options, lowerings, lineinfos
|
||||
import platform
|
||||
from os import splitFile
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
## Implements marshaling for the VM.
|
||||
|
||||
import streams, json, intsets, tables, ast, astalgo, idents, types, msgs,
|
||||
options
|
||||
options, lineinfos
|
||||
|
||||
proc ptrToInt(x: PNode): int {.inline.} =
|
||||
result = cast[int](x) # don't skip alignment
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@
|
|||
## * Computing an aliasing relation based on the assignments. This relation
|
||||
## 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
|
||||
debug = false
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import compiler / [options, commands, modules, sem,
|
|||
passes, passaux, msgs, nimconf,
|
||||
extccomp, condsyms,
|
||||
sigmatch, ast, scriptconfig,
|
||||
idents, modulegraphs, vm, prefixmatches]
|
||||
idents, modulegraphs, vm, prefixmatches, lineinfos]
|
||||
|
||||
when defined(windows):
|
||||
import winlean
|
||||
|
|
@ -109,7 +109,7 @@ proc sexp(s: Suggest): SexpNode =
|
|||
let qp = if s.qualifiedPath.isNil: @[] else: s.qualifiedPath
|
||||
result = convertSexp([
|
||||
s.section,
|
||||
s.symkind,
|
||||
TSymKind s.symkind,
|
||||
qp.map(newSString),
|
||||
s.filePath,
|
||||
s.forth,
|
||||
|
|
@ -141,20 +141,19 @@ proc listEpc(): SexpNode =
|
|||
methodDesc.add(docstring)
|
||||
result.add(methodDesc)
|
||||
|
||||
proc findNode(n: PNode): PSym =
|
||||
proc findNode(n: PNode; trackPos: TLineInfo): PSym =
|
||||
#echo "checking node ", n.info
|
||||
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:
|
||||
for i in 0 ..< safeLen(n):
|
||||
let res = n.sons[i].findNode
|
||||
let res = findNode(n[i], trackPos)
|
||||
if res != nil: return res
|
||||
|
||||
proc symFromInfo(graph: ModuleGraph; gTrackPos: TLineInfo): PSym =
|
||||
let m = graph.getModule(gTrackPos.fileIndex)
|
||||
#echo m.isNil, " I knew it ", gTrackPos.fileIndex
|
||||
proc symFromInfo(graph: ModuleGraph; trackPos: TLineInfo): PSym =
|
||||
let m = graph.getModule(trackPos.fileIndex)
|
||||
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;
|
||||
graph: ModuleGraph; cache: IdentCache) =
|
||||
|
|
@ -163,12 +162,12 @@ proc execute(cmd: IdeCmd, file, dirtyfile: string, line, col: int;
|
|||
"[" & $line & ":" & $col & "]")
|
||||
conf.ideCmd = cmd
|
||||
if cmd == ideChk:
|
||||
msgs.structuredErrorHook = errorHook
|
||||
msgs.writelnHook = myLog
|
||||
conf.structuredErrorHook = errorHook
|
||||
conf.writelnHook = myLog
|
||||
else:
|
||||
msgs.structuredErrorHook = nil
|
||||
msgs.writelnHook = myLog
|
||||
if cmd == ideUse and suggestVersion != 0:
|
||||
conf.structuredErrorHook = nil
|
||||
conf.writelnHook = myLog
|
||||
if cmd == ideUse and conf.suggestVersion != 0:
|
||||
graph.resetAllModules()
|
||||
var isKnownFile = true
|
||||
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)
|
||||
else: msgs.setDirtyFile(conf, dirtyIdx, nil)
|
||||
|
||||
gTrackPos = newLineInfo(dirtyIdx, line, col)
|
||||
gTrackPosAttached = false
|
||||
conf.m.trackPos = newLineInfo(dirtyIdx, line, col)
|
||||
conf.m.trackPosAttached = false
|
||||
conf.errorCounter = 0
|
||||
if suggestVersion == 1:
|
||||
if conf.suggestVersion == 1:
|
||||
graph.usageSym = nil
|
||||
if not isKnownFile:
|
||||
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:
|
||||
discard "no need to recompile anything"
|
||||
else:
|
||||
|
|
@ -193,11 +192,11 @@ proc execute(cmd: IdeCmd, file, dirtyfile: string, line, col: int;
|
|||
if conf.ideCmd != ideMod:
|
||||
graph.compileProject(cache, modIdx)
|
||||
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:
|
||||
listUsages(conf, u)
|
||||
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;
|
||||
graph: ModuleGraph; cache: IdentCache) =
|
||||
|
|
@ -457,16 +456,16 @@ proc mainThread(graph: ModuleGraph; cache: IdentCache) =
|
|||
else:
|
||||
writelnToChannel(line)
|
||||
|
||||
msgs.writelnHook = wrHook
|
||||
suggestionResultHook = sugResultHook
|
||||
conf.writelnHook = wrHook
|
||||
conf.suggestionResultHook = sugResultHook
|
||||
graph.doStopCompile = proc (): bool = requests.peek() > 0
|
||||
var idle = 0
|
||||
var cachedMsgs: CachedMsgs = @[]
|
||||
while true:
|
||||
let (hasData, req) = requests.tryRecv()
|
||||
if hasData:
|
||||
msgs.writelnHook = wrHook
|
||||
suggestionResultHook = sugResultHook
|
||||
conf.writelnHook = wrHook
|
||||
conf.suggestionResultHook = sugResultHook
|
||||
execCmd(req, graph, cache, cachedMsgs)
|
||||
idle = 0
|
||||
else:
|
||||
|
|
@ -475,11 +474,11 @@ proc mainThread(graph: ModuleGraph; cache: IdentCache) =
|
|||
if idle == 20 and gRefresh:
|
||||
# we use some nimsuggest activity to enable a lazy recompile:
|
||||
conf.ideCmd = ideChk
|
||||
msgs.writelnHook = proc (s: string) = discard
|
||||
conf.writelnHook = proc (s: string) = discard
|
||||
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))
|
||||
suggestionResultHook = proc (s: Suggest) = discard
|
||||
conf.suggestionResultHook = proc (s: Suggest) = discard
|
||||
recompileFullProject(graph, cache)
|
||||
|
||||
var
|
||||
|
|
@ -502,8 +501,8 @@ proc mainCommand(graph: ModuleGraph; cache: IdentCache) =
|
|||
# do not stop after the first error:
|
||||
conf.errorMax = high(int)
|
||||
# do not print errors, but log them
|
||||
msgs.writelnHook = proc (s: string) = log(s)
|
||||
msgs.structuredErrorHook = nil
|
||||
conf.writelnHook = proc (s: string) = log(s)
|
||||
conf.structuredErrorHook = nil
|
||||
|
||||
# compile the project before showing any input so that we already
|
||||
# can answer questions right away:
|
||||
|
|
@ -555,8 +554,8 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string; conf: ConfigRef) =
|
|||
gMode = mepc
|
||||
conf.verbosity = 0 # Port number gotta be first.
|
||||
of "debug": incl(conf.globalOptions, optIdeDebug)
|
||||
of "v2": suggestVersion = 0
|
||||
of "v1": suggestVersion = 1
|
||||
of "v2": conf.suggestVersion = 0
|
||||
of "v1": conf.suggestVersion = 1
|
||||
of "tester":
|
||||
gMode = mstdin
|
||||
gEmitEof = true
|
||||
|
|
@ -568,7 +567,7 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string; conf: ConfigRef) =
|
|||
else:
|
||||
gRefresh = true
|
||||
of "maxresults":
|
||||
suggestMaxResults = parseInt(p.val)
|
||||
conf.suggestMaxResults = parseInt(p.val)
|
||||
else: processSwitch(pass, p, conf)
|
||||
of cmdArgument:
|
||||
let a = unixToNativePath(p.key)
|
||||
|
|
@ -589,7 +588,7 @@ proc handleCmdLine(cache: IdentCache; conf: ConfigRef) =
|
|||
else:
|
||||
processCmdLine(passCmd1, "", conf)
|
||||
if gMode != mstdin:
|
||||
msgs.writelnHook = proc (msg: string) = discard
|
||||
conf.writelnHook = proc (msg: string) = discard
|
||||
if conf.projectName != "":
|
||||
try:
|
||||
conf.projectFull = canonicalizePath(conf, conf.projectName)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue