diff options
author | Araq <rumpf_a@web.de> | 2017-03-08 15:59:34 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2017-03-08 15:59:34 +0100 |
commit | 4d0d6c47bd58d42c38e66acacf271823f6f1b7f2 (patch) | |
tree | 4ce02a8e8e5ddaa9d0822e2ddae6ba2ed630bc93 | |
parent | 0596c11775427128138fa9a95e5f66d4674373c7 (diff) | |
download | Nim-4d0d6c47bd58d42c38e66acacf271823f6f1b7f2.tar.gz |
bugfix: consider type contexts properly
-rw-r--r-- | compiler/semdata.nim | 1 | ||||
-rw-r--r-- | compiler/suggest.nim | 74 |
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) |