summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2015-01-29 03:08:41 +0100
committerAraq <rumpf_a@web.de>2015-01-29 03:08:41 +0100
commit8710a3738470e19e0d05c8e68db0803100caf3d8 (patch)
tree2169fe70ef9b4acf33379d5d6e33ffbd0c9d06ec /compiler
parentebda8e89e15e3af88822fb2dd57c108830609ec6 (diff)
downloadNim-8710a3738470e19e0d05c8e68db0803100caf3d8.tar.gz
nimsuggest: sane dirty buffer handling
Diffstat (limited to 'compiler')
-rw-r--r--compiler/commands.nim9
-rw-r--r--compiler/main.nim6
-rw-r--r--compiler/msgs.nim38
-rw-r--r--compiler/nimsuggest/nimsuggest.nim34
-rw-r--r--compiler/options.nim6
-rw-r--r--compiler/passes.nim2
-rw-r--r--compiler/service.nim2
-rw-r--r--compiler/suggest.nim6
-rw-r--r--compiler/syntaxes.nim4
9 files changed, 51 insertions, 56 deletions
diff --git a/compiler/commands.nim b/compiler/commands.nim
index a438ea566..78fa9249c 100644
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -252,10 +252,11 @@ proc trackDirty(arg: string, info: TLineInfo) =
   if parseUtils.parseInt(a[3], column) <= 0:
     localError(info, errInvalidNumber, a[2])
   
-  gDirtyBufferIdx = a[0].fileInfoIdx
-  gDirtyOriginalIdx = a[1].fileInfoIdx
- 
-  gTrackPos = newLineInfo(gDirtyBufferIdx, line, column)
+  let dirtyOriginalIdx = a[1].fileInfoIdx
+  if dirtyOriginalIdx >= 0:
+    msgs.setDirtyFile(dirtyOriginalIdx, a[0])
+
+  gTrackPos = newLineInfo(dirtyOriginalIdx, line, column)
 
 proc track(arg: string, info: TLineInfo) = 
   var a = arg.split(',')
diff --git a/compiler/main.nim b/compiler/main.nim
index 4cf9adc0d..06dcad7b0 100644
--- a/compiler/main.nim
+++ b/compiler/main.nim
@@ -169,9 +169,9 @@ proc commandSuggest =
     # cache in a state where "no recompilation is necessary", but the
     # cgen pass was never executed at all.
     commandCompileToC()
-    if gDirtyBufferIdx != 0:
-      discard compileModule(gDirtyBufferIdx, {sfDirty})
-      resetModule(gDirtyBufferIdx)
+    let gDirtyBufferIdx = gTrackPos.fileIndex
+    discard compileModule(gDirtyBufferIdx, {sfDirty})
+    resetModule(gDirtyBufferIdx)
   else:
     msgs.gErrorMax = high(int)  # do not stop after first error
     semanticPasses()
diff --git a/compiler/msgs.nim b/compiler/msgs.nim
index fff5638da..35a121769 100644
--- a/compiler/msgs.nim
+++ b/compiler/msgs.nim
@@ -454,6 +454,9 @@ type
                                #   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'
 
   TLineInfo*{.final.} = object # This is designed to be as small as possible,
                                # because it is used
@@ -597,18 +600,7 @@ proc msgQuit*(x: int8) = quit x
 proc msgQuit*(x: string) = quit x
 
 proc suggestQuit*() =
-  when true:
-    raise newException(ESuggestDone, "suggest done")
-  else:
-    if not isServing:
-      assert false
-      quit(0)
-    elif isWorkingWithDirtyBuffer:
-      # No need to compile the rest if we are working with a
-      # throw-away buffer. Incomplete dot expressions frequently
-      # found in dirty buffers will result in errors few steps
-      # from now anyway.
-      raise newException(ESuggestDone, "suggest done")
+  raise newException(ESuggestDone, "suggest done")
 
 # this format is understood by many text editors: it is the same that
 # Borland and Freepascal use
@@ -644,6 +636,18 @@ proc toFullPath*(fileIdx: int32): string =
   if fileIdx < 0: result = "???"
   else: result = fileInfos[fileIdx].fullPath
 
+proc setDirtyFile*(fileIdx: int32; filename: string) =
+  assert fileIdx >= 0
+  fileInfos[fileIdx].dirtyFile = filename
+
+proc toFullPathConsiderDirty*(fileIdx: int32): string =
+  if fileIdx < 0:
+    result = "???"
+  elif not fileInfos[fileIdx].dirtyFile.isNil:
+    result = fileInfos[fileIdx].dirtyFile
+  else:
+    result = fileInfos[fileIdx].fullPath
+
 template toFilename*(info: TLineInfo): string =
   info.fileIndex.toFilename
 
@@ -651,12 +655,12 @@ template toFullPath*(info: TLineInfo): string =
   info.fileIndex.toFullPath
 
 proc toMsgFilename*(info: TLineInfo): string =
-  if info.fileIndex < 0: result = "???"
+  if info.fileIndex < 0:
+    result = "???"
+  elif gListFullPaths:
+    result = fileInfos[info.fileIndex].fullPath
   else:
-    if gListFullPaths:
-      result = fileInfos[info.fileIndex].fullPath
-    else:
-      result = fileInfos[info.fileIndex].projPath
+    result = fileInfos[info.fileIndex].projPath
 
 proc toLinenumber*(info: TLineInfo): int {.inline.} = 
   result = info.line
diff --git a/compiler/nimsuggest/nimsuggest.nim b/compiler/nimsuggest/nimsuggest.nim
index 3a447effb..6edea06e5 100644
--- a/compiler/nimsuggest/nimsuggest.nim
+++ b/compiler/nimsuggest/nimsuggest.nim
@@ -37,7 +37,7 @@ var
 
 const
   seps = {':', ';', ' ', '\t'}
-  Help = "usage: sug|con|def|use dirtybuffer.nim[;originalfile.nim]:line:col\n"&
+  Help = "usage: sug|con|def|use file.nim[;dirtyfile.nim]:line:col\n"&
          "type 'quit' to quit\n" &
          "type 'debug' to toggle debug mode on/off\n" &
          "type 'terse' to toggle terse mode on/off"
@@ -59,6 +59,10 @@ proc action(cmd: string) =
       incl(gGlobalOptions, sw)
     return
 
+  template err() =
+    echo Help
+    return
+
   var opc = ""
   var i = parseIdent(cmd, opc, 0)
   case opc.normalize
@@ -71,35 +75,33 @@ proc action(cmd: string) =
   of "quit": quit()
   of "debug": toggle optIdeDebug
   of "terse": toggle optIdeTerse
-  else:
-    echo Help
-    return
+  else: err()
   var dirtyfile = ""
   var orig = ""
-  i = parseQuoted(cmd, dirtyfile, i)
+  i = parseQuoted(cmd, orig, i)
   if cmd[i] == ';':
-    i = parseQuoted(cmd, orig, i+1)
+    i = parseQuoted(cmd, dirtyfile, i+1)
   i += skipWhile(cmd, seps, i)
   var line, col = -1
   i += parseInt(cmd, line, i)
   i += skipWhile(cmd, seps, i)
   i += parseInt(cmd, col, i)
-  if dirtyfile.len != 0:
-    gDirtyBufferIdx = dirtyfile.fileInfoIdx
-    gDirtyOriginalIdx = if orig.len != 0: orig.fileInfoIdx else: gDirtyBufferIdx
-  else:
-    discard "use the same filename as in the last command"
-  resetModule gDirtyBufferIdx
-  if gDirtyBufferIdx != gProjectMainIdx:
+
+  if orig.len == 0: err()
+  let dirtyIdx = orig.fileInfoIdx
+
+  if dirtyfile.len != 0: msgs.setDirtyFile(dirtyIdx, dirtyfile)
+  else: msgs.setDirtyFile(dirtyIdx, nil)
+
+  resetModule dirtyIdx
+  if dirtyIdx != gProjectMainIdx:
     resetModule gProjectMainIdx
-  gTrackPos = newLineInfo(gDirtyBufferIdx, line, col)
+  gTrackPos = newLineInfo(dirtyIdx, line, col)
   #echo dirtyfile, gDirtyBufferIdx, " project ", gProjectMainIdx
   gErrorCounter = 0
   compileProject()
 
 proc serve() =
-  gDirtyBufferIdx = gProjectMainIdx
-  gDirtyOriginalIdx = gProjectMainIdx
   # do not stop after the first error:
   msgs.gErrorMax = high(int)
   if gUseStdin:
diff --git a/compiler/options.nim b/compiler/options.nim
index 0a1fbebc1..d6d9389f5 100644
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -114,18 +114,12 @@ var
   gLastCmdTime*: float        # when caas is enabled, we measure each command
   gListFullPaths*: bool
   isServing*: bool = false
-  gDirtyBufferIdx* = 0'i32    # indicates the fileIdx of the dirty version of
-                              # the tracked source X, saved by the CAAS client.
-  gDirtyOriginalIdx* = 0'i32  # the original source file of the dirtified buffer.
   gNoNimblePath* = false
   gExperimentalMode*: bool
 
 proc importantComments*(): bool {.inline.} = gCmd in {cmdDoc, cmdIdeTools}
 proc usesNativeGC*(): bool {.inline.} = gSelectedGC >= gcRefc
 
-template isWorkingWithDirtyBuffer*: expr =
-  gDirtyBufferIdx != 0
-
 template compilationCachePresent*: expr =
   {optCaasEnabled, optSymbolFiles} * gGlobalOptions != {}
 
diff --git a/compiler/passes.nim b/compiler/passes.nim
index 95c944410..f9c3d75f9 100644
--- a/compiler/passes.nim
+++ b/compiler/passes.nim
@@ -169,7 +169,7 @@ proc processModule(module: PSym, stream: PLLStream, rd: PRodReader) =
   if rd == nil: 
     openPasses(a, module)
     if stream == nil: 
-      let filename = fileIdx.toFullPath
+      let filename = fileIdx.toFullPathConsiderDirty
       s = llStreamOpen(filename, fmRead)
       if s == nil: 
         rawMessage(errCannotOpenFile, filename)
diff --git a/compiler/service.nim b/compiler/service.nim
index d84fdf060..1d51ef2a1 100644
--- a/compiler/service.nim
+++ b/compiler/service.nim
@@ -45,8 +45,6 @@ proc serve*(action: proc (){.nimcall.}) =
     curCaasCmd = cmd
     processCmdLine(passCmd2, cmd)
     action()
-    gDirtyBufferIdx = 0
-    gDirtyOriginalIdx = 0
     gErrorCounter = 0
 
   let typ = getConfigVar("server.type")
diff --git a/compiler/suggest.nim b/compiler/suggest.nim
index bd8341936..7f8caca6e 100644
--- a/compiler/suggest.nim
+++ b/compiler/suggest.nim
@@ -22,11 +22,7 @@ const
 
 #template sectionSuggest(): expr = "##begin\n" & getStackTrace() & "##end\n"
 
-proc origModuleName(m: PSym): string =
-  result = if m.position == gDirtyBufferIdx:
-             fileInfos[gDirtyOriginalIdx].shortName
-           else:
-             m.name.s
+template origModuleName(m: PSym): string = m.name.s
 
 proc symToStr(s: PSym, isLocal: bool, section: string, li: TLineInfo): string = 
   result = section
diff --git a/compiler/syntaxes.nim b/compiler/syntaxes.nim
index 61677a641..7f9e25f82 100644
--- a/compiler/syntaxes.nim
+++ b/compiler/syntaxes.nim
@@ -45,7 +45,7 @@ proc parseFile(fileIdx: int32): PNode =
   var 
     p: TParsers
     f: File
-  let filename = fileIdx.toFullPath
+  let filename = fileIdx.toFullPathConsiderDirty
   if not open(f, filename):
     rawMessage(errCannotOpenFile, filename)
     return 
@@ -163,7 +163,7 @@ proc evalPipe(p: var TParsers, n: PNode, filename: string,
 proc openParsers(p: var TParsers, fileIdx: int32, inputstream: PLLStream) = 
   var s: PLLStream
   p.skin = skinStandard
-  let filename = fileIdx.toFullPath
+  let filename = fileIdx.toFullPathConsiderDirty
   var pipe = parsePipe(filename, inputstream)
   if pipe != nil: s = evalPipe(p, pipe, filename, inputstream)
   else: s = inputstream