mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-18 21:40:32 +00:00
implemented 'import a as b'
This commit is contained in:
@@ -131,7 +131,7 @@ type
|
||||
nkFormalParams, # formal parameters
|
||||
nkOfInherit, # inherited from symbol
|
||||
|
||||
nkModule, # the syntax tree of a module
|
||||
nkImportAs, # a 'as' b in an import statement
|
||||
nkProcDef, # a proc
|
||||
nkMethodDef, # a method
|
||||
nkConverterDef, # a converter
|
||||
@@ -641,6 +641,11 @@ type
|
||||
# this is because in incremental compilation, when a module is about to
|
||||
# be replaced with a newer version, we must decrement the usage count
|
||||
# of all previously used generics.
|
||||
# For 'import as' we copy the module symbol but shallowCopy the 'tab'
|
||||
# and set the 'usedGenerics' to ... XXX gah! Better set module.name
|
||||
# instead? But this doesn't work either. --> We need an skModuleAlias?
|
||||
# No need, just leave it as skModule but set the owner accordingly and
|
||||
# check for the owner when touching 'usedGenerics'.
|
||||
usedGenerics*: seq[PInstantiation]
|
||||
tab*: TStrTable # interface table for modules
|
||||
else: nil
|
||||
@@ -1106,7 +1111,7 @@ proc copyType(t: PType, owner: PSym, keepId: bool): PType =
|
||||
|
||||
proc copySym(s: PSym, keepId: bool = false): PSym =
|
||||
result = newSym(s.kind, s.name, s.owner, s.info)
|
||||
result.ast = nil # BUGFIX; was: s.ast which made problems
|
||||
#result.ast = nil # BUGFIX; was: s.ast which made problems
|
||||
result.typ = s.typ
|
||||
if keepId:
|
||||
result.id = s.id
|
||||
@@ -1121,6 +1126,20 @@ proc copySym(s: PSym, keepId: bool = false): PSym =
|
||||
result.position = s.position
|
||||
result.loc = s.loc
|
||||
result.annex = s.annex # BUGFIX
|
||||
|
||||
proc createModuleAlias*(s: PSym, newIdent: PIdent, info: TLineInfo): PSym =
|
||||
result = newSym(s.kind, newIdent, s.owner, info)
|
||||
# keep ID!
|
||||
result.ast = s.ast
|
||||
result.id = s.id
|
||||
result.flags = s.flags
|
||||
system.shallowCopy(result.tab, s.tab)
|
||||
result.options = s.options
|
||||
result.position = s.position
|
||||
result.loc = s.loc
|
||||
result.annex = s.annex
|
||||
# XXX once usedGenerics is used, ensure module aliases keep working!
|
||||
assert s.usedGenerics == nil
|
||||
|
||||
proc newSym(symKind: TSymKind, Name: PIdent, owner: PSym,
|
||||
info: TLineInfo): PSym =
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
#
|
||||
# The Nimrod Compiler
|
||||
# (c) Copyright 2012 Andreas Rumpf
|
||||
# (c) Copyright 2013 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
@@ -27,12 +27,24 @@ proc getModuleName*(n: PNode): string =
|
||||
result = n.ident.s
|
||||
of nkSym:
|
||||
result = n.sym.name.s
|
||||
else:
|
||||
of nkInfix:
|
||||
if n.sons[0].kind == nkIdent and n.sons[0].ident.id == getIdent("as").id:
|
||||
# XXX hack ahead:
|
||||
n.kind = nkImportAs
|
||||
n.sons[0] = n.sons[1]
|
||||
n.sons[1] = n.sons[2]
|
||||
n.sons.setLen(2)
|
||||
return getModuleName(n.sons[0])
|
||||
# hacky way to implement 'x / y /../ z':
|
||||
result = renderTree(n, {renderNoComments}).replace(" ")
|
||||
#localError(n.info, errGenerated,
|
||||
# "invalide module name: '$1'" % renderTree(n))
|
||||
#result = ""
|
||||
of nkDotExpr:
|
||||
result = renderTree(n, {renderNoComments}).replace(".")
|
||||
of nkImportAs:
|
||||
result = getModuleName(n.sons[0])
|
||||
else:
|
||||
localError(n.info, errGenerated,
|
||||
"invalid module name: '$1'" % renderTree(n))
|
||||
result = ""
|
||||
|
||||
proc checkModuleName*(n: PNode): int32 =
|
||||
# This returns the full canonical path for a given module import
|
||||
@@ -135,15 +147,28 @@ proc importForwarded(c: PContext, n: PNode, exceptSet: TIntSet) =
|
||||
for i in 0 ..safeLen(n)-1:
|
||||
importForwarded(c, n.sons[i], exceptSet)
|
||||
|
||||
proc importModuleAs(n: PNode, realModule: PSym): PSym =
|
||||
result = realModule
|
||||
if n.kind != nkImportAs: discard
|
||||
elif n.len != 2 or n.sons[1].kind != nkIdent:
|
||||
localError(n.info, errGenerated, "module alias must be an identifier")
|
||||
elif n.sons[1].ident.id != realModule.name.id:
|
||||
# some misguided guy will write 'import abc.foo as foo' ...
|
||||
result = createModuleAlias(realModule, n.sons[1].ident, n.sons[1].info)
|
||||
|
||||
proc myImportModule(c: PContext, n: PNode): PSym =
|
||||
var f = checkModuleName(n)
|
||||
if f != InvalidFileIDX:
|
||||
result = importModuleAs(n, gImportModule(c.module, f))
|
||||
if sfDeprecated in result.flags:
|
||||
Message(n.info, warnDeprecated, result.name.s)
|
||||
|
||||
proc evalImport(c: PContext, n: PNode): PNode =
|
||||
result = n
|
||||
var emptySet: TIntSet
|
||||
for i in countup(0, sonsLen(n) - 1):
|
||||
var f = checkModuleName(n.sons[i])
|
||||
if f != InvalidFileIDX:
|
||||
var m = gImportModule(c.module, f)
|
||||
if sfDeprecated in m.flags:
|
||||
Message(n.sons[i].info, warnDeprecated, m.name.s)
|
||||
var m = myImportModule(c, n.sons[i])
|
||||
if m != nil:
|
||||
# ``addDecl`` needs to be done before ``importAllSymbols``!
|
||||
addDecl(c, m) # add symbol to symbol table of module
|
||||
importAllSymbolsExcept(c, m, emptySet)
|
||||
@@ -152,21 +177,19 @@ proc evalImport(c: PContext, n: PNode): PNode =
|
||||
proc evalFrom(c: PContext, n: PNode): PNode =
|
||||
result = n
|
||||
checkMinSonsLen(n, 2)
|
||||
var f = checkModuleName(n.sons[0])
|
||||
if f != InvalidFileIDX:
|
||||
var m = gImportModule(c.module, f)
|
||||
var m = myImportModule(c, n.sons[0])
|
||||
if m != nil:
|
||||
n.sons[0] = newSymNode(m)
|
||||
addDecl(c, m) # add symbol to symbol table of module
|
||||
for i in countup(1, sonsLen(n) - 1):
|
||||
for i in countup(1, sonsLen(n) - 1):
|
||||
if n.sons[i].kind != nkNilLit:
|
||||
importSymbol(c, n.sons[i], m)
|
||||
|
||||
proc evalImportExcept*(c: PContext, n: PNode): PNode =
|
||||
result = n
|
||||
checkMinSonsLen(n, 2)
|
||||
var f = checkModuleName(n.sons[0])
|
||||
if f != InvalidFileIDX:
|
||||
var m = gImportModule(c.module, f)
|
||||
var m = myImportModule(c, n.sons[0])
|
||||
if m != nil:
|
||||
n.sons[0] = newSymNode(m)
|
||||
addDecl(c, m) # add symbol to symbol table of module
|
||||
var exceptSet = initIntSet()
|
||||
|
||||
@@ -1088,6 +1088,17 @@ proc parseExprStmt(p: var TParser): PNode =
|
||||
addSon(result, b)
|
||||
if b.kind == nkElse: break
|
||||
|
||||
proc parseModuleName(p: var TParser, kind: TNodeKind): PNode =
|
||||
result = parseExpr(p)
|
||||
when false:
|
||||
# parseExpr already handles 'as' syntax ...
|
||||
if p.tok.tokType == tkAs and kind == nkImportStmt:
|
||||
let a = result
|
||||
result = newNodeP(nkImportAs, p)
|
||||
getTok(p)
|
||||
result.add(a)
|
||||
result.add(parseExpr(p))
|
||||
|
||||
proc parseImport(p: var TParser, kind: TNodeKind): PNode =
|
||||
#| importStmt = 'import' optInd expr
|
||||
#| ((comma expr)*
|
||||
@@ -1095,7 +1106,7 @@ proc parseImport(p: var TParser, kind: TNodeKind): PNode =
|
||||
result = newNodeP(kind, p)
|
||||
getTok(p) # skip `import` or `export`
|
||||
optInd(p, result)
|
||||
var a = parseExpr(p)
|
||||
var a = parseModuleName(p, kind)
|
||||
addSon(result, a)
|
||||
if p.tok.tokType in {tkComma, tkExcept}:
|
||||
if p.tok.tokType == tkExcept:
|
||||
@@ -1104,10 +1115,10 @@ proc parseImport(p: var TParser, kind: TNodeKind): PNode =
|
||||
optInd(p, result)
|
||||
while true:
|
||||
# was: while p.tok.tokType notin {tkEof, tkSad, tkDed}:
|
||||
a = parseExpr(p)
|
||||
if a.kind == nkEmpty: break
|
||||
a = parseModuleName(p, kind)
|
||||
if a.kind == nkEmpty: break
|
||||
addSon(result, a)
|
||||
if p.tok.tokType != tkComma: break
|
||||
if p.tok.tokType != tkComma: break
|
||||
getTok(p)
|
||||
optInd(p, a)
|
||||
#expectNl(p)
|
||||
@@ -1128,11 +1139,11 @@ proc parseIncludeStmt(p: var TParser): PNode =
|
||||
#expectNl(p)
|
||||
|
||||
proc parseFromStmt(p: var TParser): PNode =
|
||||
#| fromStmt = 'from' expr 'import' optInd expr (comma expr)*
|
||||
#| fromStmt = 'from' moduleName 'import' optInd expr (comma expr)*
|
||||
result = newNodeP(nkFromStmt, p)
|
||||
getTok(p) # skip `from`
|
||||
optInd(p, result)
|
||||
var a = parseExpr(p)
|
||||
var a = parseModuleName(p, nkImportStmt)
|
||||
addSon(result, a) #optInd(p, a);
|
||||
eat(p, tkImport)
|
||||
optInd(p, result)
|
||||
|
||||
@@ -448,6 +448,7 @@ proc lsub(n: PNode): int =
|
||||
of nkPragma: result = lcomma(n) + 4
|
||||
of nkCommentStmt: result = len(n.comment)
|
||||
of nkOfBranch: result = lcomma(n, 0, - 2) + lsub(lastSon(n)) + len("of_:_")
|
||||
of nkImportAs: result = lsub(n.sons[0]) + len("_as_") + lsub(n.sons[1])
|
||||
of nkElifBranch: result = lsons(n) + len("elif_:_")
|
||||
of nkElse: result = lsub(n.sons[0]) + len("else:_")
|
||||
of nkFinally: result = lsub(n.sons[0]) + len("finally:_")
|
||||
@@ -1191,6 +1192,11 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
|
||||
putWithSpace(g, tkColon, ":")
|
||||
gcoms(g)
|
||||
gstmts(g, lastSon(n), c)
|
||||
of nkImportAs:
|
||||
gsub(g, n.sons[0])
|
||||
put(g, tkSpaces, Space)
|
||||
putWithSpace(g, tkAs, "as")
|
||||
gsub(g, n.sons[1])
|
||||
of nkBindStmt:
|
||||
putWithSpace(g, tkBind, "bind")
|
||||
gcomma(g, n, c)
|
||||
|
||||
Reference in New Issue
Block a user