summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2017-03-08 15:59:34 +0100
committerAraq <rumpf_a@web.de>2017-03-08 15:59:34 +0100
commit4d0d6c47bd58d42c38e66acacf271823f6f1b7f2 (patch)
tree4ce02a8e8e5ddaa9d0822e2ddae6ba2ed630bc93
parent0596c11775427128138fa9a95e5f66d4674373c7 (diff)
downloadNim-4d0d6c47bd58d42c38e66acacf271823f6f1b7f2.tar.gz
bugfix: consider type contexts properly
-rw-r--r--compiler/semdata.nim1
-rw-r--r--compiler/suggest.nim74
2 files changed, 42 insertions, 33 deletions
diff --git a/compiler/semdata.nim b/compiler/semdata.nim
index ef23e40f2..d36278d03 100644
--- a/compiler/semdata.nim
+++ b/compiler/semdata.nim
@@ -113,6 +113,7 @@ type
     recursiveDep*: string
     suggestionsMade*: bool
     inTypeContext*: int
+    suggestionNode*: PNode
 
 proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair =
   result.genericSym = s
diff --git a/compiler/suggest.nim b/compiler/suggest.nim
index ebabed465..3c4bf8c09 100644
--- a/compiler/suggest.nim
+++ b/compiler/suggest.nim
@@ -525,37 +525,42 @@ proc safeSemExpr*(c: PContext, n: PNode): PNode =
   except ERecoverableError:
     result = ast.emptyNode
 
+proc sugExpr(c: PContext, node: PNode, outputs: var Suggestions; cp: TCheckPointResult) =
+  var n = findClosestDot(node)
+  if n == nil: n = node
+  if n.kind == nkDotExpr:
+    var obj = safeSemExpr(c, n.sons[0])
+    # it can happen that errnously we have collected the fieldname
+    # 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: 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 m = findClosestSym(node)
+    #if m != nil:
+    #  suggestPrefix(c, m, outputs)
+    #else:
+    let prefix = if cp == cpExact: n else: nil
+    suggestEverything(c, n, prefix, outputs)
+
 proc suggestExpr*(c: PContext, node: PNode) =
   if gTrackPos.line < 0: return
   var cp = inCheckpoint(node.info)
   if cp == cpNone: return
   # This keeps semExpr() from coming here recursively:
+  if cp == cpFuzzy:
+    c.suggestionNode = node
+    return
+
   if c.compilesContextId > 0: return
   inc(c.compilesContextId)
-
   var outputs: Suggestions = @[]
   if gIdeCmd == ideSug:
-    var n = findClosestDot(node)
-    if n == nil: n = node
-    if n.kind == nkDotExpr:
-      var obj = safeSemExpr(c, n.sons[0])
-      # it can happen that errnously we have collected the fieldname
-      # 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: 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 m = findClosestSym(node)
-      #if m != nil:
-      #  suggestPrefix(c, m, outputs)
-      #else:
-      let prefix = if cp == cpExact: n else: nil
-      suggestEverything(c, n, prefix, outputs)
-
+    sugExpr(c, node, outputs, cp)
   elif gIdeCmd == ideCon:
     var n = findClosestCall(node)
     if n == nil: n = node
@@ -583,17 +588,20 @@ proc suggestSentinel*(c: PContext) =
   if gIdeCmd != ideSug or c.module.position != gTrackPos.fileIndex: return
   if c.compilesContextId > 0: return
   inc(c.compilesContextId)
-  # suggest everything:
-  var isLocal = true
   var outputs: Suggestions = @[]
-  var scopeN = 0
-  for scope in walkScopes(c.currentScope):
-    if scope == c.topLevelScope: isLocal = false
-    dec scopeN
-    for it in items(scope.symbols):
-      var pm: PrefixMatch
-      if filterSymNoOpr(it, nil, pm):
-        outputs.add(symToSuggest(it, isLocal = isLocal, $ideSug, 0, PrefixMatch.None, false, scopeN))
+  if c.suggestionNode != nil:
+    sugExpr(c, c.suggestionNode, outputs, cpExact)
+  else:
+    # suggest everything:
+    var isLocal = true
+    var scopeN = 0
+    for scope in walkScopes(c.currentScope):
+      if scope == c.topLevelScope: isLocal = false
+      dec scopeN
+      for it in items(scope.symbols):
+        var pm: PrefixMatch
+        if filterSymNoOpr(it, nil, pm):
+          outputs.add(symToSuggest(it, isLocal = isLocal, $ideSug, 0, PrefixMatch.None, false, scopeN))
 
-  produceOutput(outputs)
   dec(c.compilesContextId)
+  produceOutput(outputs)