Skip to content

Commit

Permalink
nimsuggest: make def work for all import syntaxes (#897)
Browse files Browse the repository at this point in the history
## Summary

Fix the `def` command producing no results when used with certain import
syntaxes and styles.

* multiple-module-imports: definitions are now reported for all module
  names (e.g., `z` in `import x/[y, z]`), not only the first one
* import-as: definitions are now reported for the alias name (e.g., `z`
  in `import x/[y as z]`)
* definitions are now reported for single-module imports that use the
  bracket syntax (`x/[y]`) where the module name is on a different line
  than the opening bracket

The `def` command is usually used for goto-definition support in IDEs,
meaning that goto-definition on module names in import statements now
work for the above cases.

## Details

Instead of passing the source position of the transformed node to
`onSymImport`, the source position of the original node is passed to it.
So that the original source position can be passed to `onSymImport`,
`myImportModule` and `impMod` now take an additional `info: TLineInfo`
parameter.

For `import x as y`, a `def` of `x` is only reported on `y` right now
(and nothing is reported on `x`). Eventually, a proper `def` should
be reported on either both `x` and `y` or only on `x`.

---------

Co-authored-by: zerbina <100542850+zerbina@users.noreply.github.com>
  • Loading branch information
bung87 and zerbina authored Sep 24, 2023
1 parent 9d53547 commit f7ba754
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 8 deletions.
19 changes: 11 additions & 8 deletions compiler/modules/importer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,10 @@ proc transformImportAs(c: PContext; n: PNode): tuple[node: PNode, importHidden:
ret.node = n.processPragma
return ret

proc myImportModule(c: PContext, n: var PNode, importStmtResult: PNode): PSym =
proc myImportModule(c: PContext, n: var PNode, info: TLineInfo,
importStmtResult: PNode): PSym =
## `info` provides the source position (which may be different from the one
## of `n`) to use for symbol suggestions.
let transf = transformImportAs(c, n)
n = transf.node
let f = checkModuleName(c.config, n)
Expand Down Expand Up @@ -332,7 +335,7 @@ proc myImportModule(c: PContext, n: var PNode, importStmtResult: PNode): PSym =
localReport(c.config, n.info, reportSym(rsemDeprecated, realModule))

if c.graph.onSymImport != nil:
c.graph.onSymImport(c.graph, n.info, result, c.graph.usageSym, false)
c.graph.onSymImport(c.graph, info, result, c.graph.usageSym, false)

importStmtResult.add:
case result.kind
Expand All @@ -353,10 +356,10 @@ proc afterImport(c: PContext, m: PSym) =
else:
discard

proc impMod(c: PContext; it: PNode; importStmtResult: PNode): PNode =
proc impMod(c: PContext; it: PNode; info: TLineInfo; importStmtResult: PNode): PNode =
result = it
let
m = myImportModule(c, result, importStmtResult)
m = myImportModule(c, result, info, importStmtResult)
hasError = m.isError

if m != nil:
Expand Down Expand Up @@ -397,9 +400,9 @@ proc evalImport*(c: PContext, n: PNode): PNode =
else:
x

hasError = impMod(c, imp, result).kind == nkError or hasError
hasError = impMod(c, imp, x.info, result).kind == nkError or hasError
else:
hasError = impMod(c, it, result).kind == nkError
hasError = impMod(c, it, it.info, result).kind == nkError

if hasError:
result = c.config.wrapError(result)
Expand All @@ -409,7 +412,7 @@ proc evalFrom*(c: PContext, n: PNode): PNode =
# how they work, far too much mutation
checkMinSonsLen(n, 2, c.config)
result = newNodeI(nkFromStmt, n.info)
let m = myImportModule(c, n[0], result)
let m = myImportModule(c, n[0], n[0].info, result)
var hasError = m.isError
if m != nil:
n[0] = newSymNode(m)
Expand Down Expand Up @@ -452,7 +455,7 @@ proc readExceptSet(c: PContext, n: PNode): IntSet =
proc evalImportExcept*(c: PContext, n: PNode): PNode =
checkMinSonsLen(n, 2, c.config)
result = newNodeI(nkImportExceptStmt, n.info)
let m = myImportModule(c, n[0], result)
let m = myImportModule(c, n[0], n[0].info, result)
var hasError = m.isError

if m != nil:
Expand Down
23 changes: 23 additions & 0 deletions nimsuggest/tests/tdef_import.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
discard """
$nimsuggest --tester $file
>def $1
def;;skModule;;minclude_types;;*;;$file;;15;;15;;"";;100
>def $2
def;;skModule;;minclude_types;;*;;$file;;16;;15;;"";;100
>def $3
def;;skModule;;minclude_import;;*;;$file;;19;;10;;"";;100
>def $4
def;;skModule;;minclude_types;;*;;$file;;22;;13;;"";;100
>def $5
def;;skModule;;mstrutils;;*;;$file;;23;;15;;"";;100
"""

import fixtures/[minclude_import, minclud#[!]#e_types]
import fixtures/[minclude_types as typ#[!]#es]
# test with multi-line import statements:
import
fixtures/[
minclu#[!]#de_import
]
from fixtures/mincl#[!]#ude_types import Greet
import fixtures/mst#[!]#rutils except replace

0 comments on commit f7ba754

Please sign in to comment.