summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2013-04-09 00:15:43 +0300
committerZahary Karadjov <zahary@gmail.com>2013-04-09 00:15:43 +0300
commite7581e7b9b580ea14b3fab5bba3fe90caa86acb8 (patch)
tree93a4d2b96d6c90b1740f9c413e1813242d23cec9
parent95b28700cc38bb2d2cee2a93745c75545c2f3d89 (diff)
downloadNim-e7581e7b9b580ea14b3fab5bba3fe90caa86acb8.tar.gz
experimental support for outputting code snippets in error messages; implements #301
see #301 for description.
currently, the feature is activated by setting the verbosity level to 2 or more
-rw-r--r--compiler/msgs.nim15
-rw-r--r--compiler/options.nim6
2 files changed, 21 insertions, 0 deletions
diff --git a/compiler/msgs.nim b/compiler/msgs.nim
index bec30388c..8b45bf80c 100644
--- a/compiler/msgs.nim
+++ b/compiler/msgs.nim
@@ -506,6 +506,8 @@ var gCodegenLineInfo* = newLineInfo(int32(1), 1, 1)
 proc raiseRecoverableError*(msg: string) {.noinline, noreturn.} =
   raise newException(ERecoverableError, msg)
 
+proc sourceLine*(i: TLineInfo): PRope
+
 var
   gNotes*: TNoteKinds = {low(TNoteKind)..high(TNoteKind)} - {warnShadowIdent}
   gErrorCounter*: int = 0     # counts the number of errors
@@ -707,6 +709,11 @@ proc rawMessage*(msg: TMsgKind, arg: string) =
 var
   lastError = UnknownLineInfo()
 
+proc writeSurroundingSrc(info: TLineInfo) =
+  const indent = "  "
+  MsgWriteln(indent & info.sourceLine.data)
+  MsgWriteln(indent & repeatChar(info.col, ' ') & '^')
+
 proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string, 
                eh: TErrorHandling) =
   var frmt: string
@@ -732,6 +739,8 @@ proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string,
                   coordToStr(info.col), getMessageStr(msg, arg)]
   if not ignoreMsg:
     MsgWriteln(s)
+    if optPrintSurroundingSrc and msg in errMin..errMax:
+      info.writeSurroundingSrc
   handleError(msg, eh, s)
   
 proc Fatal*(info: TLineInfo, msg: TMsgKind, arg = "") = 
@@ -771,6 +780,12 @@ proc addSourceLine*(fileIdx: int32, line: string) =
 
 proc sourceLine*(i: TLineInfo): PRope =
   if i.fileIndex < 0: return nil
+  
+  if not optPreserveOrigSource and
+         fileInfos[i.fileIndex].lines.len == 0:
+    for line in lines(i.toFullPath):
+      addSourceLine i.fileIndex, line.string
+
   InternalAssert i.fileIndex < fileInfos.len and
                  i.line <= fileInfos[i.fileIndex].lines.len
 
diff --git a/compiler/options.nim b/compiler/options.nim
index 899332b6e..9d75ba7a6 100644
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -113,6 +113,12 @@ proc usesNativeGC*(): bool {.inline.} = gSelectedGC >= gcRefc
 template compilationCachePresent*: expr =
   {optCaasEnabled, optSymbolFiles} * gGlobalOptions != {}
 
+template optPreserveOrigSource*: expr =
+  optEmbedOrigSrc in gGlobalOptions
+
+template optPrintSurroundingSrc*: expr =
+  gVerbosity >= 2
+
 const 
   genSubDir* = "nimcache"
   NimExt* = "nim"