followup #18362: make UnusedImport work robustly (#18366)

* warnDuplicateModuleImport => hintDuplicateModuleImport
* improve DuplicateModuleImport msg, add test
This commit is contained in:
Timothee Cour 2021-06-27 11:39:16 -07:00 • committed by GitHub
commit 0b7361e938
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 186 additions and 25 deletions

View file

@ -31,7 +31,7 @@ const
proc runNimCmd(file, options = "", rtarg = ""): auto =
let fileabs = testsDir / file.unixToNativePath
# doAssert fileabs.fileExists, fileabs # disabled because this allows passing `nim r --eval:code fakefile`
let cmd = fmt"{nim} {mode} {options} --hints:off {fileabs} {rtarg}"
let cmd = fmt"{nim} {mode} --hint:all:off {options} {fileabs} {rtarg}"
result = execCmdEx(cmd)
when false: # for debugging
echo cmd
@ -352,5 +352,29 @@ running: v2
doAssert outp2 == "12345\n", outp2
doAssert status2 == 0
block: # UnusedImport
proc fn(opt: string, expected: string) =
let output = runNimCmdChk("pragmas/mused3.nim", fmt"--warning:all:off --warning:UnusedImport --hint:DuplicateModuleImport {opt}")
doAssert output == expected, opt & "\noutput:\n" & output & "expected:\n" & expected
fn("-d:case1"): """
mused3.nim(13, 8) Warning: imported and not used: 'mused3b' [UnusedImport]
"""
fn("-d:case2"): ""
fn("-d:case3"): ""
fn("-d:case4"): ""
fn("-d:case5"): ""
fn("-d:case6"): ""
fn("-d:case7"): ""
fn("-d:case8"): ""
fn("-d:case9"): ""
fn("-d:case10"): ""
when false:
fn("-d:case11"): """
Warning: imported and not used: 'm2' [UnusedImport]
"""
fn("-d:case12"): """
mused3.nim(75, 10) Hint: duplicate import of 'mused3a'; previous import here: mused3.nim(74, 10) [DuplicateModuleImport]
"""
else:
discard # only during debugging, tests added here will run with `-d:nimTestsTrunnerDebugging` enabled

76
tests/pragmas/mused3.nim Normal file
View file

@ -0,0 +1,76 @@
#[
ran from trunner
]#
# line 10
when defined case1:
from mused3a import nil
from mused3b import nil
mused3a.fn1()
when defined case2:
from mused3a as m1 import nil
m1.fn1()
when defined case3:
from mused3a import fn1
fn1()
when defined case4:
from mused3a as m1 import fn1
m1.fn1()
when defined case5:
import mused3a as m1
fn1()
when defined case6:
import mused3a except nonexistent
fn1()
when defined case7:
import mused3a
mused3a.fn1()
when defined case8:
# re-export test
import mused3a except nonexistent
gn1()
when defined case9:
# re-export test
import mused3a
gn1()
when defined case10:
#[
edge case which happens a lot in compiler code:
don't report UnusedImport for mused3b here even though it works without `import mused3b`,
because `a.b0.f0` is accessible from both mused3a and mused3b (fields are given implicit access)
]#
import mused3a
import mused3b
var a: Bar
discard a.b0.f0
when false:
when defined case11:
#[
xxx minor bug: this should give:
Warning: imported and not used: 'm2' [UnusedImport]
but doesn't, because currently implementation in `markOwnerModuleAsUsed`
only looks at `fn1`, not fully qualified call `m1.fn1()
]#
from mused3a as m1 import nil
from mused3a as m2 import nil
m1.fn1()
when defined case12:
import mused3a
import mused3a
fn1()

41
tests/pragmas/mused3a.nim Normal file
View file

@ -0,0 +1,41 @@
when defined case1:
proc fn1*() = discard
when defined case2:
proc fn1*() = discard
when defined case3:
proc fn1*() = discard
proc fn2*() = discard
when defined case4:
proc fn1*() = discard
proc fn2*() = discard
when defined case5:
proc fn1*() = discard
when defined case6:
proc fn1*() = discard
when defined case7:
proc fn1*() = discard
when defined case8:
import mused3b
export mused3b
when defined case9:
import mused3b
export mused3b
when defined case10:
import mused3b
type Bar* = object
b0*: Foo
when defined case11:
proc fn1*() = discard
when defined case12:
proc fn1*() = discard

12
tests/pragmas/mused3b.nim Normal file
View file

@ -0,0 +1,12 @@
when defined case1:
proc gn1*()=discard
when defined case8:
proc gn1*()=discard
when defined case9:
proc gn1*()=discard
when defined case10:
type Foo* = object
f0*: int