summary refs log tree commit diff stats
path: root/rod/suggest.nim
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2011-02-23 00:15:36 +0100
committerAraq <rumpf_a@web.de>2011-02-23 00:15:36 +0100
commit82514c9c1cd4f9f907501e493c7b046a66b3944a (patch)
tree2d5349e2b5f5e26b36d8838a5f4999296f98134a /rod/suggest.nim
parent310faca724a4d4a28a3fbce753fff37ad33b5f38 (diff)
downloadNim-82514c9c1cd4f9f907501e493c7b046a66b3944a.tar.gz
suggest: improvements
Diffstat (limited to 'rod/suggest.nim')
-rw-r--r--rod/suggest.nim63
1 files changed, 50 insertions, 13 deletions
diff --git a/rod/suggest.nim b/rod/suggest.nim
index bddb247c3..5e0788ae3 100644
--- a/rod/suggest.nim
+++ b/rod/suggest.nim
@@ -9,7 +9,7 @@
 
 ## This file implements features required for IDE support.
 
-import scanner, ast, astalgo, semdata, msgs, types, sigmatch
+import scanner, idents, ast, astalgo, semdata, msgs, types, sigmatch
 
 const
   sep = '\t'
@@ -64,7 +64,14 @@ proc suggestObject(n: PNode) =
   else: nil
 
 proc nameFits(c: PContext, s: PSym, n: PNode): bool = 
-  result = n.sons[0].kind == nkSym and n.sons[0].sym.name.id == s.name.id
+  var op = n.sons[0]
+  if op.kind == nkSymChoice: op = op.sons[0]
+  var opr: PIdent
+  case op.kind
+  of nkSym: opr = op.sym.name
+  of nkIdent: opr = op.ident
+  else: return false
+  result = opr.id == s.name.id
 
 proc argsFit(c: PContext, candidate: PSym, n: PNode): bool = 
   case candidate.kind 
@@ -78,11 +85,11 @@ proc argsFit(c: PContext, candidate: PSym, n: PNode): bool =
   else:
     result = false
 
-proc suggestCall*(c: PContext, n: PNode) = 
+proc suggestCall(c: PContext, n: PNode) = 
   wholeSymTab(filterSym(it) and nameFits(c, it, n) and argsFit(c, it, n))
 
 proc typeFits(c: PContext, s: PSym, firstArg: PType): bool {.inline.} = 
-  if s.typ != nil and sonsLen(s.typ) > 1:
+  if s.typ != nil and sonsLen(s.typ) > 1 and s.typ.sons[1] != nil:
     result = sigmatch.argtypeMatches(c, s.typ.sons[1], firstArg)
 
 proc suggestOperations(c: PContext, n: PNode, typ: PType) =
@@ -132,21 +139,51 @@ proc suggestFieldAccess(c: PContext, n: PNode) =
       # fallback: 
       suggestEverything(c, n)
 
-proc suggestExpr*(c: PContext, n: PNode) = 
-  var cp = msgs.inCheckpoint(n.info)
+proc interestingNode(n: PNode): bool {.inline.} =
+  result = n.kind == nkDotExpr
+
+proc findClosestNode(n: PNode): PNode = 
+  if msgs.inCheckpoint(n.info) == cpExact: 
+    result = n
+    echo "came here"
+    debug result
+  elif n.kind notin {nkNone..nkNilLit}:
+    for i in 0.. <sonsLen(n):
+      if interestingNode(n.sons[i]):
+        result = findClosestNode(n.sons[i])
+        if result != nil: return
+
+var recursiveCheck = 0
+
+proc suggestExpr*(c: PContext, node: PNode) = 
+  var cp = msgs.inCheckpoint(node.info)
   if cp == cpNone: return
+  # HACK: This keeps semExpr() from coming here recursively:
+  if recursiveCheck > 0: return
+  inc(recursiveCheck)
+  var n = findClosestNode(node)
+  if n == nil: n = node
+  else: cp = msgs.inCheckpoint(n.info)
   block:
+    debug n
     case n.kind
     of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, 
         nkCallStrLit, nkMacroStmt: 
-      var a = copyNode(n)
-      for i in 0..sonsLen(n)-1:
-        # use as many typed arguments as possible:
-        var x = c.semExpr(c, n.sons[i])
-        if x.kind == nkEmpty or x.typ == nil: break
+      when false:
+        # this provides "context information", not "type suggestion":
+        var a = copyNode(n)
+        var x = c.semExpr(c, n.sons[0])
+        if x.kind == nkEmpty or x.typ == nil: x = n.sons[0]
         addSon(a, x)
-      suggestCall(c, n)
-      break
+        for i in 1..sonsLen(n)-1:
+          # use as many typed arguments as possible:
+          var x = c.semExpr(c, n.sons[i])
+          if x.kind == nkEmpty or x.typ == nil: break
+          addSon(a, x)
+        suggestCall(c, a)
+        break
+      else:
+        nil
     of nkDotExpr: 
       if cp == cpExact:
         var obj = c.semExpr(c, n.sons[0])