diff --git a/compiler/lineinfos.nim b/compiler/lineinfos.nim index 331268d6ad7d7..e1e0a4bc812c2 100644 --- a/compiler/lineinfos.nim +++ b/compiler/lineinfos.nim @@ -181,6 +181,12 @@ const hintMin* = hintSuccess hintMax* = high(TMsgKind) +proc msgToStr*(msg: TMsgKind): string = + case msg + of warnMin..warnMax: WarningsToStr[ord(msg) - ord(warnMin)] + of hintMin..hintMax: HintsToStr[ord(msg) - ord(hintMin)] + else: "" # we could at least do $msg - prefix `err` + static: doAssert HintsToStr.len == ord(hintMax) - ord(hintMin) + 1 doAssert WarningsToStr.len == ord(warnMax) - ord(warnMin) + 1 diff --git a/compiler/main.nim b/compiler/main.nim index 21c0695f6c0b7..88f1890dedcfc 100644 --- a/compiler/main.nim +++ b/compiler/main.nim @@ -345,12 +345,10 @@ proc mainCommand*(graph: ModuleGraph) = var hints = newJObject() # consider factoring with `listHints` for a in hintMin..hintMax: - let key = lineinfos.HintsToStr[ord(a) - ord(hintMin)] - hints[key] = %(a in conf.notes) + hints[a.msgToStr] = %(a in conf.notes) var warnings = newJObject() for a in warnMin..warnMax: - let key = lineinfos.WarningsToStr[ord(a) - ord(warnMin)] - warnings[key] = %(a in conf.notes) + warnings[a.msgToStr] = %(a in conf.notes) var dumpdata = %[ (key: "version", val: %VersionAsString), diff --git a/compiler/modules.nim b/compiler/modules.nim index 47d946a01bba5..d6e82d694d557 100644 --- a/compiler/modules.nim +++ b/compiler/modules.nim @@ -125,7 +125,7 @@ proc compileSystemModule*(graph: ModuleGraph) = proc wantMainModule*(conf: ConfigRef) = if conf.projectFull.isEmpty: - fatal(conf, newLineInfo(conf, AbsoluteFile"command line", 1, 1), errGenerated, + fatal(conf, newLineInfo(conf, AbsoluteFile(commandLineDesc), 1, 1), errGenerated, "command expects a filename") conf.projectMainIdx = fileInfoIdx(conf, addFileExt(conf.projectFull, NimExt)) diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 7523d2d8b804f..6bf4d82d29160 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -13,6 +13,13 @@ import import std/private/miscdollars type InstantiationInfo = typeof(instantiationInfo()) +template instLoc(): InstantiationInfo = instantiationInfo(-2, fullPaths = true) + +template flushDot(conf, stdorr) = + ## safe to call multiple times + if conf.lastMsgWasDot: + conf.lastMsgWasDot = false + write(stdorr, "\n") proc toCChar*(c: char; result: var string) = case c @@ -37,7 +44,6 @@ proc makeCString*(s: string): Rope = res.add('\"') result.add(rope(res)) - proc newFileInfo(fullPath: AbsoluteFile, projPath: RelativeFile): TFileInfo = result.fullPath = fullPath #shallow(result.fullPath) @@ -111,7 +117,6 @@ proc newLineInfo*(fileInfoIdx: FileIndex, line, col: int): TLineInfo = proc newLineInfo*(conf: ConfigRef; filename: AbsoluteFile, line, col: int): TLineInfo {.inline.} = result = newLineInfo(fileInfoIdx(conf, filename), line, col) - proc concat(strings: openArray[string]): string = var totalLen = 0 for s in strings: totalLen += s.len @@ -147,6 +152,7 @@ const # but column numbers start with 0, however most editors expect # first column to be 1, so we need to +1 here ColOffset* = 1 + commandLineDesc* = "command line" proc getInfoContextLen*(conf: ConfigRef): int = return conf.m.msgContext.len proc setInfoContextLen*(conf: ConfigRef; L: int) = setLen(conf.m.msgContext, L) @@ -162,9 +168,6 @@ proc getInfoContext*(conf: ConfigRef; index: int): TLineInfo = if i >=% conf.m.msgContext.len: result = unknownLineInfo else: result = conf.m.msgContext[i].info -const - commandLineDesc = "command line" - template toFilename*(conf: ConfigRef; fileIdx: FileIndex): string = if fileIdx.int32 < 0 or conf == nil: (if fileIdx == commandLineIdx: commandLineDesc else: "???") @@ -277,11 +280,6 @@ type msgSkipHook ## skip message hook even if it is present MsgFlags* = set[MsgFlag] -template flushDot(stdorr) = - if conf.lastMsgWasDot: - write(stdorr, "\n") - conf.lastMsgWasDot = false - proc msgWriteln*(conf: ConfigRef; s: string, flags: MsgFlags = {}) = ## Writes given message string to stderr by default. ## If ``--stdout`` option is given, writes to stdout instead. If message hook @@ -295,12 +293,12 @@ proc msgWriteln*(conf: ConfigRef; s: string, flags: MsgFlags = {}) = conf.writelnHook(s) elif optStdout in conf.globalOptions or msgStdout in flags: if eStdOut in conf.m.errorOutputs: - flushDot(stdout) + flushDot(conf, stdout) writeLine(stdout, s) flushFile(stdout) else: if eStdErr in conf.m.errorOutputs: - flushDot(stderr) + flushDot(conf, stderr) writeLine(stderr, s) # On Windows stderr is fully-buffered when piped, regardless of C std. when defined(windows): @@ -345,25 +343,25 @@ proc msgWrite(conf: ConfigRef; s: string) = stderr write(stdOrr, s) flushFile(stdOrr) + conf.lastMsgWasDot = true # subsequent writes need `flushDot` template styledMsgWriteln*(args: varargs[typed]) = if not isNil(conf.writelnHook): callIgnoringStyle(callWritelnHook, nil, args) elif optStdout in conf.globalOptions: if eStdOut in conf.m.errorOutputs: - flushDot(stdout) + flushDot(conf, stdout) callIgnoringStyle(writeLine, stdout, args) flushFile(stdout) - else: - if eStdErr in conf.m.errorOutputs: - flushDot(stderr) - if optUseColors in conf.globalOptions: - callStyledWriteLineStderr(args) - else: - callIgnoringStyle(writeLine, stderr, args) - # On Windows stderr is fully-buffered when piped, regardless of C std. - when defined(windows): - flushFile(stderr) + elif eStdErr in conf.m.errorOutputs: + flushDot(conf, stderr) + if optUseColors in conf.globalOptions: + callStyledWriteLineStderr(args) + else: + callIgnoringStyle(writeLine, stderr, args) + # On Windows stderr is fully-buffered when piped, regardless of C std. + when defined(windows): + flushFile(stderr) proc msgKindToString*(kind: TMsgKind): string = # later versions may provide translated error messages @@ -434,57 +432,6 @@ proc writeContext(conf: ConfigRef; lastinfo: TLineInfo) = proc ignoreMsgBecauseOfIdeTools(conf: ConfigRef; msg: TMsgKind): bool = msg >= errGenerated and conf.cmd == cmdIdeTools and optIdeDebug notin conf.globalOptions -proc rawMessage*(conf: ConfigRef; msg: TMsgKind, args: openArray[string]) = - var - title: string - color: ForegroundColor - kind: string - sev: Severity - case msg - of errMin..errMax: - sev = Severity.Error - writeContext(conf, unknownLineInfo) - title = ErrorTitle - color = ErrorColor - of warnMin..warnMax: - sev = Severity.Warning - if not conf.hasWarn(msg): return - writeContext(conf, unknownLineInfo) - title = if msg in conf.warningAsErrors: ErrorTitle else: WarningTitle - color = WarningColor - kind = WarningsToStr[ord(msg) - ord(warnMin)] - inc(conf.warnCounter) - of hintMin..hintMax: - sev = Severity.Hint - if not conf.hasHint(msg): return - title = HintTitle - color = HintColor - if msg != hintUserRaw: kind = HintsToStr[ord(msg) - ord(hintMin)] - inc(conf.hintCounter) - let s = msgKindToString(msg) % args - - if conf.structuredErrorHook != nil: - conf.structuredErrorHook(conf, unknownLineInfo, - s & (if kind.len > 0: KindFormat % kind else: ""), sev) - - if not ignoreMsgBecauseOfIdeTools(conf, msg): - if msg == hintProcessing: - msgWrite(conf, ".") - conf.lastMsgWasDot = true - else: - if conf.lastMsgWasDot: - msgWrite(conf, "\n") - conf.lastMsgWasDot = false - if kind.len > 0: - styledMsgWriteln(color, title, resetStyle, s, - KindColor, `%`(KindFormat, kind)) - else: - styledMsgWriteln(color, title, resetStyle, s) - handleError(conf, msg, doAbort, s) - -proc rawMessage*(conf: ConfigRef; msg: TMsgKind, arg: string) = - rawMessage(conf, msg, [arg]) - proc addSourceLine(conf: ConfigRef; fileIdx: FileIndex, line: string) = conf.m.fileInfos[fileIdx.int32].lines.add line @@ -517,108 +464,111 @@ proc formatMsg*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg: string): s conf.toFileLineCol(info) & " " & title & getMessageStr(msg, arg) proc liMessage(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg: string, - eh: TErrorHandling, info2: InstantiationInfo) {.noinline.} = + eh: TErrorHandling, info2: InstantiationInfo, isRaw = false) {.noinline.} = var title: string color: ForegroundColor - kind: string ignoreMsg = false sev: Severity + let kind = if msg != hintUserRaw: msg.msgToStr else: "" # xxx not sure why hintUserRaw is special case msg of errMin..errMax: sev = Severity.Error writeContext(conf, info) title = ErrorTitle color = ErrorColor - # 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 - conf.m.lastError = info + when false: + # we try to filter error messages so that not two error message + # in the same file and line are produced: + # xxx `lastError` is only used in this disabled code; but could be useful to revive + ignoreMsg = conf.m.lastError == info and info != unknownLineInfo and eh != doAbort + if info != unknownLineInfo: conf.m.lastError = info of warnMin..warnMax: sev = Severity.Warning ignoreMsg = not conf.hasWarn(msg) if not ignoreMsg: writeContext(conf, info) title = if msg in conf.warningAsErrors: ErrorTitle else: WarningTitle color = WarningColor - kind = WarningsToStr[ord(msg) - ord(warnMin)] inc(conf.warnCounter) of hintMin..hintMax: sev = Severity.Hint ignoreMsg = not conf.hasHint(msg) title = HintTitle color = HintColor - if msg != hintUserRaw: kind = HintsToStr[ord(msg) - ord(hintMin)] inc(conf.hintCounter) - let x = conf.toFileLineCol(info) & " " - let s = getMessageStr(msg, arg) + let s = if isRaw: arg else: getMessageStr(msg, arg) if not ignoreMsg: + let loc = if info != unknownLineInfo: conf.toFileLineCol(info) & " " else: "" + var kindmsg = if kind.len > 0: KindFormat % kind else: "" if conf.structuredErrorHook != nil: - conf.structuredErrorHook(conf, info, s & (if kind.len > 0: KindFormat % kind else: ""), sev) + conf.structuredErrorHook(conf, info, s & kindmsg, sev) if not ignoreMsgBecauseOfIdeTools(conf, msg): - if kind.len > 0: - styledMsgWriteln(styleBright, x, resetStyle, color, title, resetStyle, s, - KindColor, `%`(KindFormat, kind)) + if msg == hintProcessing: + msgWrite(conf, ".") else: - styledMsgWriteln(styleBright, x, resetStyle, color, title, resetStyle, s) - if conf.hasHint(hintSource): - conf.writeSurroundingSrc(info) - if conf.hasHint(hintMsgOrigin): - styledMsgWriteln(styleBright, toFileLineCol(info2), resetStyle, - " compiler msg initiated here", KindColor, - KindFormat % HintsToStr[ord(hintMsgOrigin) - ord(hintMin)], - resetStyle) - + styledMsgWriteln(styleBright, loc, resetStyle, color, title, resetStyle, s, KindColor, kindmsg) + if conf.hasHint(hintSource) and info != unknownLineInfo: + conf.writeSurroundingSrc(info) + if conf.hasHint(hintMsgOrigin): + styledMsgWriteln(styleBright, toFileLineCol(info2), resetStyle, + " compiler msg initiated here", KindColor, + KindFormat % hintMsgOrigin.msgToStr, + resetStyle) handleError(conf, msg, eh, s) +template rawMessage*(conf: ConfigRef; msg: TMsgKind, args: openArray[string]) = + let arg = msgKindToString(msg) % args + liMessage(conf, unknownLineInfo, msg, arg, eh = doAbort, instLoc(), isRaw = true) + +template rawMessage*(conf: ConfigRef; msg: TMsgKind, arg: string) = + liMessage(conf, unknownLineInfo, msg, arg, eh = doAbort, instLoc()) + template fatal*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg = "") = - # this fixes bug #7080 so that it is at least obvious 'fatal' - # was executed. + # this fixes bug #7080 so that it is at least obvious 'fatal' was executed. conf.m.errorOutputs = {eStdOut, eStdErr} - const info2 = instantiationInfo(-1, fullPaths = true) - liMessage(conf, info, msg, arg, doAbort, info2) + liMessage(conf, info, msg, arg, doAbort, instLoc()) template globalError*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg = "") = - const info2 = instantiationInfo(-1, fullPaths = true) - liMessage(conf, info, msg, arg, doRaise, info2) + liMessage(conf, info, msg, arg, doRaise, instLoc()) template globalError*(conf: ConfigRef; info: TLineInfo, arg: string) = - const info2 = instantiationInfo(-1, fullPaths = true) - liMessage(conf, info, errGenerated, arg, doRaise, info2) + liMessage(conf, info, errGenerated, arg, doRaise, instLoc()) template localError*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg = "") = - const info2 = instantiationInfo(-1, fullPaths = true) - liMessage(conf, info, msg, arg, doNothing, info2) + liMessage(conf, info, msg, arg, doNothing, instLoc()) template localError*(conf: ConfigRef; info: TLineInfo, arg: string) = - const info2 = instantiationInfo(-1, fullPaths = true) - liMessage(conf, info, errGenerated, arg, doNothing, info2) + liMessage(conf, info, errGenerated, arg, doNothing, instLoc()) template localError*(conf: ConfigRef; info: TLineInfo, format: string, params: openArray[string]) = - const info2 = instantiationInfo(-1, fullPaths = true) - liMessage(conf, info, errGenerated, format % params, doNothing, info2) + liMessage(conf, info, errGenerated, format % params, doNothing, instLoc()) template message*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg = "") = - const info2 = instantiationInfo(-1, fullPaths = true) - liMessage(conf, info, msg, arg, doNothing, info2) + liMessage(conf, info, msg, arg, doNothing, instLoc()) -proc internalError*(conf: ConfigRef; info: TLineInfo, errMsg: string) = +proc internalErrorImpl(conf: ConfigRef; info: TLineInfo, errMsg: string, info2: InstantiationInfo) = if conf.cmd == cmdIdeTools and conf.structuredErrorHook.isNil: return - const info2 = instantiationInfo(-1, fullPaths = true) writeContext(conf, info) liMessage(conf, info, errInternal, errMsg, doAbort, info2) -proc internalError*(conf: ConfigRef; errMsg: string) = - if conf.cmd == cmdIdeTools and conf.structuredErrorHook.isNil: return - writeContext(conf, unknownLineInfo) - rawMessage(conf, errInternal, errMsg) +template internalError*(conf: ConfigRef; info: TLineInfo, errMsg: string) = + internalErrorImpl(conf, info, errMsg, instLoc()) -template assertNotNil*(conf: ConfigRef; e): untyped = - if e == nil: internalError(conf, $instantiationInfo()) - e +template internalError*(conf: ConfigRef; errMsg: string) = + internalErrorImpl(conf, unknownLineInfo, errMsg, instLoc()) template internalAssert*(conf: ConfigRef, e: bool) = - if not e: internalError(conf, $instantiationInfo()) + # xxx merge with globalAssert from PR #14324 + if not e: + const info2 = instLoc() + let arg = info2.toFileLineCol + internalErrorImpl(conf, unknownLineInfo, arg, info2) + +template lintReport*(conf: ConfigRef; info: TLineInfo, beau, got: string) = + let m = "'$2' should be: '$1'" % [beau, got] + let msg = if optStyleError in conf.globalOptions: errGenerated else: hintName + liMessage(conf, info, msg, m, doNothing, instLoc()) proc quotedFilename*(conf: ConfigRef; i: TLineInfo): Rope = if i.fileIndex.int32 < 0: @@ -628,25 +578,9 @@ proc quotedFilename*(conf: ConfigRef; i: TLineInfo): Rope = else: 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: " ", - lineinfos.WarningsToStr[ord(warn) - ord(warnMin)] - ]) - -proc listHints*(conf: ConfigRef) = - msgWriteln(conf, "Hints:") - for hint in hintMin..hintMax: - msgWriteln(conf, " [$1] $2" % [ - if hint in conf.notes: "x" else: " ", - lineinfos.HintsToStr[ord(hint) - ord(hintMin)] - ]) - -proc lintReport*(conf: ConfigRef; info: TLineInfo, beau, got: string) = - let m = "'$2' should be: '$1'" % [beau, got] - if optStyleError in conf.globalOptions: - localError(conf, info, m) - else: - message(conf, info, hintName, m) +template listMsg(title, r) = + msgWriteln(conf, title) + for a in r: msgWriteln(conf, " [$1] $2" % [if a in conf.notes: "x" else: " ", a.msgToStr]) + +proc listWarnings*(conf: ConfigRef) = listMsg("Warnings:", warnMin..warnMax) +proc listHints*(conf: ConfigRef) = listMsg("Hints:", hintMin..hintMax) diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 278384fc44ed9..5a2c08de266b8 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -321,7 +321,8 @@ proc makeTypeDesc*(c: PContext, typ: PType): PType = proc makeTypeSymNode*(c: PContext, typ: PType, info: TLineInfo): PNode = let typedesc = newTypeS(tyTypeDesc, c) incl typedesc.flags, tfCheckedForDestructor - typedesc.addSonSkipIntLit(assertNotNil(c.config, typ)) + internalAssert(c.config, typ != nil) + typedesc.addSonSkipIntLit(typ) let sym = newSym(skType, c.cache.idAnon, getCurrOwner(c), info, c.config.options).linkTo(typedesc) return newSymNode(sym, info) diff --git a/compiler/syntaxes.nim b/compiler/syntaxes.nim index 29ccf4794b4f9..c3f3bc0dc40ba 100644 --- a/compiler/syntaxes.nim +++ b/compiler/syntaxes.nim @@ -121,9 +121,9 @@ proc applyFilter(p: var TParsers, n: PNode, filename: AbsoluteFile, if f != filtNone: assert p.config != nil if p.config.hasHint(hintCodeBegin): - rawMessage(p.config, hintCodeBegin, []) + rawMessage(p.config, hintCodeBegin, "") msgWriteln(p.config, result.s) - rawMessage(p.config, hintCodeEnd, []) + rawMessage(p.config, hintCodeEnd, "") proc evalPipe(p: var TParsers, n: PNode, filename: AbsoluteFile, start: PLLStream): PLLStream =