diff options
-rw-r--r-- | compiler/jsgen.nim | 4 | ||||
-rw-r--r-- | compiler/msgs.nim | 65 | ||||
-rw-r--r-- | lib/std/private/miscdollars.nim | 15 | ||||
-rw-r--r-- | lib/system/assertions.nim | 4 | ||||
-rw-r--r-- | lib/system/excpt.nim | 8 | ||||
-rw-r--r-- | lib/system/jssys.nim | 9 | ||||
-rw-r--r-- | tests/js/t7224.nim | 9 |
7 files changed, 68 insertions, 46 deletions
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index eb9e97fac..c4ee36dbf 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -2243,7 +2243,7 @@ proc genProcBody(p: PProc, prc: PSym): Rope = if hasFrameInfo(p): result = frameCreate(p, makeJSString(prc.owner.name.s & '.' & prc.name.s), - makeJSString(toFilename(p.config, prc.info))) + makeJSString(toFilenameOption(p.config, prc.info.fileIndex, foStacktrace))) else: result = nil if p.beforeRetNeeded: @@ -2583,7 +2583,7 @@ proc genModule(p: PProc, n: PNode) = if optStackTrace in p.options: p.body.add(frameCreate(p, makeJSString("module " & p.module.module.name.s), - makeJSString(toFilename(p.config, p.module.module.info)))) + makeJSString(toFilenameOption(p.config, p.module.module.info.fileIndex, foStacktrace)))) var transformedN = transformStmt(p.module.graph, p.module.module, n) if sfInjectDestructors in p.module.module.flags: transformedN = injectDestructorCalls(p.module.graph, p.module.module, transformedN) diff --git a/compiler/msgs.nim b/compiler/msgs.nim index c0d98007b..43ed8f2a8 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -10,6 +10,7 @@ import options, strutils, os, tables, ropes, terminal, macros, lineinfos, pathutils +import std/private/miscdollars proc toCChar*(c: char; result: var string) = case c @@ -132,7 +133,6 @@ proc suggestQuit*() = # this format is understood by many text editors: it is the same that # Borland and Freepascal use const - PosFormat = "$1($2, $3) " KindFormat = " [$1]" KindColor = fgCyan ErrorTitle = "Error: " @@ -213,16 +213,38 @@ template toFullPath*(conf: ConfigRef; info: TLineInfo): string = template toFullPathConsiderDirty*(conf: ConfigRef; info: TLineInfo): string = string toFullPathConsiderDirty(conf, info.fileIndex) +type FilenameOption* = enum + foAbs # absolute path, eg: /pathto/bar/foo.nim + foRelProject # relative to project path, eg: ../foo.nim + foMagicSauce # magic sauce, shortest of (foAbs, foRelProject) + foName # lastPathPart, eg: foo.nim + foShort # foName without extension, eg: foo + foStacktrace # if optExcessiveStackTrace: foAbs else: foName + +proc toFilenameOption*(conf: ConfigRef, fileIdx: FileIndex, opt: FilenameOption): string = + case opt + of foAbs: result = toFullPath(conf, fileIdx) + of foRelProject: result = toProjPath(conf, fileIdx) + of foMagicSauce: + let + absPath = toFullPath(conf, fileIdx) + relPath = toProjPath(conf, fileIdx) + result = if (optListFullPaths in conf.globalOptions) or + (relPath.len > absPath.len) or + (relPath.count("..") > 2): + absPath + else: + relPath + of foName: result = toProjPath(conf, fileIdx).lastPathPart + of foShort: result = toFilename(conf, fileIdx) + of foStacktrace: + if optExcessiveStackTrace in conf.globalOptions: + result = toFilenameOption(conf, fileIdx, foAbs) + else: + result = toFilenameOption(conf, fileIdx, foName) + proc toMsgFilename*(conf: ConfigRef; info: FileIndex): string = - let - absPath = toFullPath(conf, info) - relPath = toProjPath(conf, info) - result = if (optListFullPaths in conf.globalOptions) or - (relPath.len > absPath.len) or - (relPath.count("..") > 2): - absPath - else: - relPath + toFilenameOption(conf, info, foMagicSauce) template toMsgFilename*(conf: ConfigRef; info: TLineInfo): string = toMsgFilename(conf, info.fileIndex) @@ -234,9 +256,7 @@ proc toColumn*(info: TLineInfo): int {.inline.} = result = info.col proc toFileLineCol*(conf: ConfigRef; info: TLineInfo): string {.inline.} = - # consider calling `helpers.lineInfoToString` instead - result = toMsgFilename(conf, info) & "(" & $info.line & ", " & - $(info.col + ColOffset) & ")" + result.toLocation(toMsgFilename(conf, info), info.line.int, info.col.int + ColOffset) proc `$`*(conf: ConfigRef; info: TLineInfo): string = toFileLineCol(conf, info) @@ -322,10 +342,6 @@ template styledMsgWriteln*(args: varargs[typed]) = when defined(windows): flushFile(stderr) -proc coordToStr(coord: int): string = - if coord == -1: result = "???" - else: result = $coord - proc msgKindToString*(kind: TMsgKind): string = # later versions may provide translated error messages result = MsgKindToStr[kind] @@ -389,12 +405,7 @@ proc writeContext(conf: ConfigRef; lastinfo: TLineInfo) = instantiationFrom else: instantiationOfFrom.format(context.detail) - styledMsgWriteln(styleBright, - PosFormat % [toMsgFilename(conf, context.info), - coordToStr(context.info.line.int), - coordToStr(context.info.col+ColOffset)], - resetStyle, - message) + styledMsgWriteln(styleBright, conf.toFileLineCol(context.info), " ", resetStyle, message) info = context.info proc ignoreMsgBecauseOfIdeTools(conf: ConfigRef; msg: TMsgKind): bool = @@ -473,10 +484,7 @@ proc formatMsg*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg: string): s of warnMin..warnMax: WarningTitle of hintMin..hintMax: HintTitle else: ErrorTitle - result = PosFormat % [toMsgFilename(conf, info), coordToStr(info.line.int), - coordToStr(info.col+ColOffset)] & - title & - getMessageStr(msg, arg) + conf.toFileLineCol(info) & " " & title & getMessageStr(msg, arg) proc liMessage(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg: string, eh: TErrorHandling) = @@ -511,8 +519,7 @@ proc liMessage(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg: string, color = HintColor if msg != hintUserRaw: kind = HintsToStr[ord(msg) - ord(hintMin)] inc(conf.hintCounter) - let x = PosFormat % [toMsgFilename(conf, info), coordToStr(info.line.int), - coordToStr(info.col+ColOffset)] + let x = conf.toFileLineCol(info) & " " let s = getMessageStr(msg, arg) if not ignoreMsg: diff --git a/lib/std/private/miscdollars.nim b/lib/std/private/miscdollars.nim new file mode 100644 index 000000000..a41cf1bc1 --- /dev/null +++ b/lib/std/private/miscdollars.nim @@ -0,0 +1,15 @@ +template toLocation*(result: var string, file: string | cstring, line: int, col: int) = + ## avoids spurious allocations + # Hopefully this can be re-used everywhere so that if a user needs to customize, + # it can be done in a single place. + result.add file + if line > 0: + result.add "(" + # simplify this after moving moving `include strmantle` above import assertions` + when declared(addInt): result.addInt line + else: result.add $line + if col > 0: + result.add ", " + when declared(addInt): result.addInt col + else: result.add $col + result.add ")" diff --git a/lib/system/assertions.nim b/lib/system/assertions.nim index 9a1bdc7bc..ca3bd7bc1 100644 --- a/lib/system/assertions.nim +++ b/lib/system/assertions.nim @@ -1,17 +1,17 @@ when not declared(sysFatal): include "system/fatal" +import std/private/miscdollars # --------------------------------------------------------------------------- # helpers type InstantiationInfo = tuple[filename: string, line: int, column: int] proc `$`(x: int): string {.magic: "IntToStr", noSideEffect.} - proc `$`(info: InstantiationInfo): string = # The +1 is needed here # instead of overriding `$` (and changing its meaning), consider explicit name. - info.filename & "(" & $info.line & ", " & $(info.column+1) & ")" + result.toLocation(info.filename, info.line, info.column+1) # --------------------------------------------------------------------------- diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index f85c10598..747b145ae 100644 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -10,6 +10,8 @@ # Exception handling code. Carefully coded so that tiny programs which do not # use the heap (and nor exceptions) do not include the GC or memory allocator. +import std/private/miscdollars + var errorMessageWriter*: (proc(msg: string) {.tags: [WriteIOEffect], benign, nimcall.}) @@ -240,11 +242,7 @@ proc auxWriteStackTrace(f: PFrame; s: var seq[StackTraceEntry]) = template addFrameEntry(s: var string, f: StackTraceEntry|PFrame) = var oldLen = s.len - add(s, f.filename) - if f.line > 0: - add(s, '(') - add(s, $f.line) - add(s, ')') + s.toLocation(f.filename, f.line, 0) for k in 1..max(1, 25-(s.len-oldLen)): add(s, ' ') add(s, f.procname) when NimStackTraceMsgs: diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim index 106283490..705a6a208 100644 --- a/lib/system/jssys.nim +++ b/lib/system/jssys.nim @@ -8,6 +8,7 @@ # include system/indexerrors +import std/private/miscdollars proc log*(s: cstring) {.importc: "console.log", varargs, nodecl.} @@ -70,7 +71,7 @@ proc getCurrentExceptionMsg*(): string = proc auxWriteStackTrace(f: PCallFrame): string = type - TempFrame = tuple[procname: cstring, line: int] + TempFrame = tuple[procname: cstring, line: int, filename: cstring] var it = f i = 0 @@ -79,6 +80,7 @@ proc auxWriteStackTrace(f: PCallFrame): string = while it != nil and i <= high(tempFrames): tempFrames[i].procname = it.procname tempFrames[i].line = it.line + tempFrames[i].filename = it.filename inc(i) inc(total) it = it.prev @@ -92,10 +94,9 @@ proc auxWriteStackTrace(f: PCallFrame): string = add(result, $(total-i)) add(result, " calls omitted) ...\n") for j in countdown(i-1, 0): + result.toLocation($tempFrames[j].filename, tempFrames[j].line, 0) + add(result, " at ") add(result, tempFrames[j].procname) - if tempFrames[j].line > 0: - add(result, ", line: ") - add(result, $tempFrames[j].line) add(result, "\n") proc rawWriteStackTrace(): string = diff --git a/tests/js/t7224.nim b/tests/js/t7224.nim index be9d0ae9c..77fef10a7 100644 --- a/tests/js/t7224.nim +++ b/tests/js/t7224.nim @@ -1,10 +1,11 @@ discard """ cmd: "nim $target $options --stackTrace:on --lineTrace:on $file" outputsub: ''' -t7224.aaa, line: 21 -t7224.bbb, line: 18 -t7224.ccc, line: 15 -t7224.ddd, line: 12 +t7224.nim(25) at module t7224 +t7224.nim(22) at t7224.aaa +t7224.nim(19) at t7224.bbb +t7224.nim(16) at t7224.ccc +t7224.nim(13) at t7224.ddd ''' """ |