-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Experimental typeImports #8660
Experimental typeImports #8660
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -68,6 +68,22 @@ proc rawImportSymbol(c: PContext, s: PSym) = | |
if s.kind == skConverter: addConverter(c, s) | ||
if hasPattern(s): addPattern(c, s) | ||
|
||
proc maybeImportForType(c: PContext, s: PSym, t: PType) = | ||
## Imports a symbol only if it has a strict relation with a type: | ||
## | ||
## - Proc refers to the type on any of its input or output values. | ||
## | ||
## TODO: generics are not matched currently. | ||
## | ||
case s.kind | ||
of skProcKinds: | ||
for tt in s.typ.sons.items: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Question: shall I avoid using iterators in the compiler code? maybe they are not as efficient as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to avoid them, they are zero-cost. |
||
if t == tt: | ||
rawImportSymbol(c, s) | ||
break | ||
else: | ||
discard | ||
|
||
proc importSymbol(c: PContext, n: PNode, fromMod: PSym) = | ||
let ident = lookups.considerQuotedIdent(c, n) | ||
let s = strTableGet(fromMod.tab, ident) | ||
|
@@ -88,6 +104,19 @@ proc importSymbol(c: PContext, n: PNode, fromMod: PSym) = | |
if e.name.id != s.name.id: internalError(c.config, n.info, "importSymbol: 3") | ||
rawImportSymbol(c, e) | ||
e = nextIdentIter(it, fromMod.tab) | ||
|
||
of skType: | ||
# import the type as expected | ||
rawImportSymbol(c, s) | ||
|
||
# types can bring attached their related symbols too | ||
if typeImports in c.features: | ||
var i: TTabIter | ||
var ss = initTabIter(i, fromMod.tab) | ||
while ss != nil: | ||
maybeImportForType(c, ss, s.typ) | ||
ss = nextIter(i, fromMod.tab) | ||
|
||
else: rawImportSymbol(c, s) | ||
|
||
proc importAllSymbolsExcept(c: PContext, fromMod: PSym, exceptSet: IntSet) = | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6333,6 +6333,24 @@ It's also possible to use ``from module import nil`` if one wants to import | |
the module but wants to enforce fully qualified access to every symbol | ||
in ``module``. | ||
|
||
By using the experimental feature ``typeImports`` it's possible to bring | ||
all the symbols directly related to a type. Any callable that has the imported | ||
type as one of its arguments or return type gets automatically included with the | ||
import. | ||
|
||
.. code-block:: nim | ||
:test: "nim c $1" | ||
|
||
{.experimental: "typeImports".} | ||
|
||
from colors import Color | ||
|
||
# to string and proc imported | ||
let pink = rgb(255, 192, 203) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this example shows that it's not enough the type is the return type of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sorry, I don't understand, could you rephrase? Maybe it should demonstrate what's going on more explicitly There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I mean that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh, yeah, you're right. I implemented it initially without taking into account the return type but it forced to include the factory function
I think it balances for the implicity on factories, specially since many times it's kind of obvious that they are creating the type. |
||
echo $pink | ||
# color constants are not imported though, this would fail: | ||
# echo $colBlue | ||
|
||
|
||
Export statement | ||
~~~~~~~~~~~~~~~~ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
discard """ | ||
output: "#FFC0CB" | ||
""" | ||
|
||
{.experimental: "typeImports".} | ||
|
||
from colors import Color | ||
|
||
# to string and proc imported | ||
let pink = rgb(255, 192, 203) | ||
echo $pink |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
discard """ | ||
file: "ttypeimportfail.nim" | ||
errormsg: "undeclared identifier: 'colBlue'" | ||
""" | ||
|
||
{.experimental: "typeImports".} | ||
|
||
from colors import Color | ||
|
||
# constants of the type not imported | ||
discard colBlue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this should be done though. Requires a bit more code, will show you how to do that later.