diff options
Diffstat (limited to 'compiler')
76 files changed, 647 insertions, 646 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index ec727544e..85278f9ef 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -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 diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index 1b6417964..7079e77cc 100644 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -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) diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim index f481e4d63..75cd3d35d 100644 --- a/compiler/ccgutils.nim +++ b/compiler/ccgutils.nim @@ -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 = diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 1c5544d4d..2d4fbf174 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -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 diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim index ce3fc2f90..daad1b1ce 100644 --- a/compiler/cgendata.nim +++ b/compiler/cgendata.nim @@ -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 diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim index da3ffaa61..5b58e6498 100644 --- a/compiler/cgmeth.nim +++ b/compiler/cgmeth.nim @@ -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) diff --git a/compiler/commands.nim b/compiler/commands.nim index 50bc6a770..efb7e2427 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -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}: diff --git a/compiler/configuration.nim b/compiler/configuration.nim index bd9651c08..22e0b834e 100644 --- a/compiler/configuration.nim +++ b/compiler/configuration.nim @@ -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 diff --git a/compiler/destroyer.nim b/compiler/destroyer.nim index 0dc90b552..dfb11883f 100644 --- a/compiler/destroyer.nim +++ b/compiler/destroyer.nim @@ -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} diff --git a/compiler/dfa.nim b/compiler/dfa.nim index aab1d9b4b..013242f62 100644 --- a/compiler/dfa.nim +++ b/compiler/dfa.nim @@ -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 diff --git a/compiler/docgen.nim b/compiler/docgen.nim index c40d524d8..708340f35 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -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] diff --git a/compiler/docgen2.nim b/compiler/docgen2.nim index 5e36cd356..0db3b89d1 100644 --- a/compiler/docgen2.nim +++ b/compiler/docgen2.nim @@ -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 diff --git a/compiler/evaltempl.nim b/compiler/evaltempl.nim index a1b5e731c..e3dd0f342 100644 --- a/compiler/evaltempl.nim +++ b/compiler/evaltempl.nim @@ -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) diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index 23db9cbe1..615b8c1e1 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -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: diff --git a/compiler/filter_tmpl.nim b/compiler/filter_tmpl.nim index 6c16a0b4e..09455ced7 100644 --- a/compiler/filter_tmpl.nim +++ b/compiler/filter_tmpl.nim @@ -11,7 +11,7 @@ import llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options, - renderer, filters + renderer, filters, lineinfos type TParseState = enum diff --git a/compiler/gorgeimpl.nim b/compiler/gorgeimpl.nim index b175d23c5..44ad46136 100644 --- a/compiler/gorgeimpl.nim +++ b/compiler/gorgeimpl.nim @@ -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] = "" diff --git a/compiler/guards.nim b/compiler/guards.nim index 1748254d6..99bb51fce 100644 --- a/compiler/guards.nim +++ b/compiler/guards.nim @@ -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, diff --git a/compiler/hlo.nim b/compiler/hlo.nim index 8251e3179..bbbcb4e56 100644 --- a/compiler/hlo.nim +++ b/compiler/hlo.nim @@ -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 diff --git a/compiler/importer.nim b/compiler/importer.nim index 2dec05d66..22e90b50e 100644 --- a/compiler/importer.nim +++ b/compiler/importer.nim @@ -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 diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 96f35c76b..747572dd3 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -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 diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index f9795a766..02682af44 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -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 diff --git a/compiler/lexer.nim b/compiler/lexer.nim index cf23c9479..1249f84b0 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -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 diff --git a/compiler/liftlocals.nim b/compiler/liftlocals.nim index 4603d357b..bf8f9f994 100644 --- a/compiler/liftlocals.nim +++ b/compiler/liftlocals.nim @@ -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 diff --git a/compiler/lineinfos.nim b/compiler/lineinfos.nim new file mode 100644 index 000000000..0ff6a5ccd --- /dev/null +++ b/compiler/lineinfos.nim @@ -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} diff --git a/compiler/lookups.nim b/compiler/lookups.nim index a67b027cb..8be843161 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -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) diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index 38e9800d3..b5be6ebbb 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -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.} = diff --git a/compiler/magicsys.nim b/compiler/magicsys.nim index 2f021743e..1ca1dc5d8 100644 --- a/compiler/magicsys.nim +++ b/compiler/magicsys.nim @@ -11,7 +11,7 @@ import ast, astalgo, hashes, msgs, platform, nversion, times, idents, rodread, - modulegraphs + modulegraphs, lineinfos export createMagic diff --git a/compiler/main.nim b/compiler/main.nim index 7e0ac102c..bf37a107d 100644 --- a/compiler/main.nim +++ b/compiler/main.nim @@ -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 diff --git a/compiler/modulegraphs.nim b/compiler/modulegraphs.nim index d8fa4cedd..00f230a12 100644 --- a/compiler/modulegraphs.nim +++ b/compiler/modulegraphs.nim @@ -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 diff --git a/compiler/modulepaths.nim b/compiler/modulepaths.nim index 8d21fa755..e9ee172a4 100644 --- a/compiler/modulepaths.nim +++ b/compiler/modulepaths.nim @@ -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 diff --git a/compiler/modules.nim b/compiler/modules.nim index 09d5d60b5..5dde755fa 100644 --- a/compiler/modules.nim +++ b/compiler/modules.nim @@ -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: diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 151291ffb..197d6ca2a 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -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)] ]) diff --git a/compiler/nim.nim b/compiler/nim.nim index d3e00017f..456a7bdac 100644 --- a/compiler/nim.nim +++ b/compiler/nim.nim @@ -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 diff --git a/compiler/nimblecmd.nim b/compiler/nimblecmd.nim index 8305b01f5..9a23535bf 100644 --- a/compiler/nimblecmd.nim +++ b/compiler/nimblecmd.nim @@ -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): diff --git a/compiler/nimconf.nim b/compiler/nimconf.nim index 6cb5bab0f..04903e690 100644 --- a/compiler/nimconf.nim +++ b/compiler/nimconf.nim @@ -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 diff --git a/compiler/nimfix/pretty.nim b/compiler/nimfix/pretty.nim index 2fa2a2c3d..cd05325b0 100644 --- a/compiler/nimfix/pretty.nim +++ b/compiler/nimfix/pretty.nim @@ -14,7 +14,7 @@ import strutils, os, intsets, strtabs import ".." / [options, ast, astalgo, msgs, semdata, ropes, idents, - configuration] + lineinfos] import prettybase type diff --git a/compiler/nimfix/prettybase.nim b/compiler/nimfix/prettybase.nim index 89c48ae6e..f530c8012 100644 --- a/compiler/nimfix/prettybase.nim +++ b/compiler/nimfix/prettybase.nim @@ -8,7 +8,7 @@ # import strutils, lexbase, streams -import ".." / [ast, msgs, idents, options] +import ".." / [ast, msgs, lineinfos, idents, options] from os import splitFile type diff --git a/compiler/nimsets.nim b/compiler/nimsets.nim index c7a12433f..b00353e20 100644 --- a/compiler/nimsets.nim +++ b/compiler/nimsets.nim @@ -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 = diff --git a/compiler/nversion.nim b/compiler/nversion.nim index caa818d79..4b8cf7100 100644 --- a/compiler/nversion.nim +++ b/compiler/nversion.nim @@ -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. diff --git a/compiler/options.nim b/compiler/options.nim index 6acf78909..48713161c 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -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 diff --git a/compiler/parser.nim b/compiler/parser.nim index 82e6549ed..621eabeb2 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -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 diff --git a/compiler/passaux.nim b/compiler/passaux.nim index 568fb4c23..1ac461188 100644 --- a/compiler/passaux.nim +++ b/compiler/passaux.nim @@ -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 diff --git a/compiler/passes.nim b/compiler/passes.nim index 26e33185c..3fe7ce481 100644 --- a/compiler/passes.nim +++ b/compiler/passes.nim @@ -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 diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 19431613c..7c7f1a792 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -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") diff --git a/compiler/prefixmatches.nim b/compiler/prefixmatches.nim index 00e2c537d..246d1ae5e 100644 --- a/compiler/prefixmatches.nim +++ b/compiler/prefixmatches.nim @@ -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 diff --git a/compiler/renderer.nim b/compiler/renderer.nim index 53e16edd2..748cf9d1c 100644 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -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 diff --git a/compiler/reorder.nim b/compiler/reorder.nim index e4ba221e3..932df9bca 100644 --- a/compiler/reorder.nim +++ b/compiler/reorder.nim @@ -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 diff --git a/compiler/rod.nim b/compiler/rod.nim index c144f15ef..82f556b3b 100644 --- a/compiler/rod.nim +++ b/compiler/rod.nim @@ -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 diff --git a/compiler/rodread.nim b/compiler/rodread.nim index 9c834a410..dc9b1c61d 100644 --- a/compiler/rodread.nim +++ b/compiler/rodread.nim @@ -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) diff --git a/compiler/rodwrite.nim b/compiler/rodwrite.nim index a5574fdf0..0b27418b3 100644 --- a/compiler/rodwrite.nim +++ b/compiler/rodwrite.nim @@ -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 diff --git a/compiler/ropes.nim b/compiler/ropes.nim index 297343a39..973f16916 100644 --- a/compiler/ropes.nim +++ b/compiler/ropes.nim @@ -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): diff --git a/compiler/scriptconfig.nim b/compiler/scriptconfig.nim index 30e5e4803..32ee04b58 100644 --- a/compiler/scriptconfig.nim +++ b/compiler/scriptconfig.nim @@ -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 diff --git a/compiler/sem.nim b/compiler/sem.nim index 8b616bd84..b7dd1df7a 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -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 diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 1de5a55cc..894d2ebb2 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -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: diff --git a/compiler/semdata.nim b/compiler/semdata.nim index e88f19768..be682189e 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -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 diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 64a5861e2..5e244fd09 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -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: diff --git a/compiler/semfold.nim b/compiler/semfold.nim index b60f6b8bd..10a223ea2 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -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 diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 8f06e748e..d3b1695ae 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -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: diff --git a/compiler/seminst.nim b/compiler/seminst.nim index e95b94553..95b631850 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -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 diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index e60d34e82..bd1cd5a7f 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -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)) diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 2ba2a6ace..db6bb32ff 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -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: diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 055ac3425..eb3376ff5 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -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: diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index 352bc5c6b..bc2621e42 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -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, {}) diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 993cacb5e..a24972d04 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -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 = diff --git a/compiler/service.nim b/compiler/service.nim index f1a988ae5..47fe25ea1 100644 --- a/compiler/service.nim +++ b/compiler/service.nim @@ -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: diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 8fdf10afb..e1961e666 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -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 diff --git a/compiler/suggest.nim b/compiler/suggest.nim index 0700b4140..391906c3f 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -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) diff --git a/compiler/syntaxes.nim b/compiler/syntaxes.nim index cb12629b4..069f65eee 100644 --- a/compiler/syntaxes.nim +++ b/compiler/syntaxes.nim @@ -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 diff --git a/compiler/transf.nim b/compiler/transf.nim index 4bd57d9d3..d5edb4ec8 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -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 diff --git a/compiler/types.nim b/compiler/types.nim index 4b6cb105c..887f6249f 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -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 diff --git a/compiler/vm.nim b/compiler/vm.nim index ecee319d0..03f63013c 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -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 diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim index e10a62006..9c31dda24 100644 --- a/compiler/vmdef.nim +++ b/compiler/vmdef.nim @@ -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 diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim index 45d6b81c3..d4a4c0b88 100644 --- a/compiler/vmdeps.nim +++ b/compiler/vmdeps.nim @@ -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: diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 282530d27..4a7ab9b79 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -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 diff --git a/compiler/vmmarshal.nim b/compiler/vmmarshal.nim index f38be7c29..c39650048 100644 --- a/compiler/vmmarshal.nim +++ b/compiler/vmmarshal.nim @@ -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 diff --git a/compiler/writetracking.nim b/compiler/writetracking.nim index c0f7b7b20..1ea1deb2d 100644 --- a/compiler/writetracking.nim +++ b/compiler/writetracking.nim @@ -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 |