diff options
-rw-r--r-- | changelog.md | 2 | ||||
-rw-r--r-- | compiler/importer.nim | 13 | ||||
-rw-r--r-- | compiler/semexprs.nim | 23 | ||||
-rw-r--r-- | doc/manual.rst | 3 | ||||
-rw-r--r-- | tests/modules/definitions.nim | 4 | ||||
-rw-r--r-- | tests/modules/proxy_module.nim | 3 |
6 files changed, 41 insertions, 7 deletions
diff --git a/changelog.md b/changelog.md index 2a1e80573..cbefbc421 100644 --- a/changelog.md +++ b/changelog.md @@ -108,6 +108,8 @@ - Thread-local variables can now be declared inside procs. This implies all the effects of the `global` pragma. +- Nim now supports `except` clause in the export statement. + ### Tool changes - ``jsondoc2`` has been renamed ``jsondoc``, similar to how ``doc2`` was renamed diff --git a/compiler/importer.nim b/compiler/importer.nim index f4903e6c4..a5c361864 100644 --- a/compiler/importer.nim +++ b/compiler/importer.nim @@ -16,6 +16,13 @@ import proc evalImport*(c: PContext, n: PNode): PNode proc evalFrom*(c: PContext, n: PNode): PNode +proc readExceptSet*(n: PNode): IntSet = + assert n.kind in {nkImportExceptStmt, nkExportExceptStmt} + result = initIntSet() + for i in 1 ..< n.len: + let ident = lookups.considerQuotedIdent(n[i]) + result.incl(ident.id) + proc importPureEnumField*(c: PContext; s: PSym) = var check = strTableGet(c.importTable.symbols, s.name) if check == nil: @@ -198,9 +205,5 @@ proc evalImportExcept*(c: PContext, n: PNode): PNode = if m != nil: n.sons[0] = newSymNode(m) addDecl(c, m, n.info) # add symbol to symbol table of module - var exceptSet = initIntSet() - for i in countup(1, sonsLen(n) - 1): - let ident = lookups.considerQuotedIdent(n.sons[i]) - exceptSet.incl(ident.id) - importAllSymbolsExcept(c, m, exceptSet) + importAllSymbolsExcept(c, m, readExceptSet(n)) #importForwarded(c, m.ast, exceptSet) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 5ef9916ad..1ef284a77 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -2160,9 +2160,25 @@ proc semBlock(c: PContext, n: PNode): PNode = closeScope(c) dec(c.p.nestedBlockCounter) +proc semExportExcept(c: PContext, n: PNode): PNode = + let moduleName = semExpr(c, n[0]) + if moduleName.kind != nkSym or moduleName.sym.kind != skModule: + localError(n.info, "The export/except syntax expects a module name") + return + let exceptSet = readExceptSet(n) + let exported = moduleName.sym + strTableAdd(c.module.tab, exported) + var i: TTabIter + var s = initTabIter(i, exported.tab) + while s != nil: + if s.kind in ExportableSymKinds+{skModule} and + s.name.id notin exceptSet: + strTableAdd(c.module.tab, s) + s = nextIter(i, exported.tab) + result = n + proc semExport(c: PContext, n: PNode): PNode = var x = newNodeI(n.kind, n.info) - #let L = if n.kind == nkExportExceptStmt: L = 1 else: n.len for i in 0..<n.len: let a = n.sons[i] var o: TOverloadIter @@ -2448,9 +2464,12 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = of nkIncludeStmt: #if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "include") result = evalInclude(c, n) - of nkExportStmt, nkExportExceptStmt: + of nkExportStmt: if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "export") result = semExport(c, n) + of nkExportExceptStmt: + if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "export") + result = semExportExcept(c, n) of nkPragmaBlock: result = semPragmaBlock(c, n) of nkStaticStmt: diff --git a/doc/manual.rst b/doc/manual.rst index 1a4ed19b7..44e2ee5b5 100644 --- a/doc/manual.rst +++ b/doc/manual.rst @@ -6298,6 +6298,9 @@ modules don't need to import a module's dependencies: var x: MyObject echo $x +When the exported symbol is another module, all of its definitions will +be forwarded. You can use an ``except`` list to exclude some of the symbols. + Note on paths ----------- In module related statements, if any part of the module name / diff --git a/tests/modules/definitions.nim b/tests/modules/definitions.nim new file mode 100644 index 000000000..edc6eaa6d --- /dev/null +++ b/tests/modules/definitions.nim @@ -0,0 +1,4 @@ +var v*: int +proc p* = echo "proc p called" +template t* = echo "template t expanded" + diff --git a/tests/modules/proxy_module.nim b/tests/modules/proxy_module.nim new file mode 100644 index 000000000..c244688cd --- /dev/null +++ b/tests/modules/proxy_module.nim @@ -0,0 +1,3 @@ +import definitions +export definitions except p + |