mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-29 01:14:41 +00:00
78 lines
2.7 KiB
Nim
78 lines
2.7 KiB
Nim
#
|
|
# See the file "copying.txt", included in this
|
|
# distribution, for details about the copyright.
|
|
#
|
|
|
|
import ast, renderer, gorgeimpl, strutils, msgs, options, idents, ospaths
|
|
|
|
proc lookupPackage(pkg, subdir: PNode): string =
|
|
let sub = if subdir != nil: renderTree(subdir, {renderNoComments}).replace(" ") else: ""
|
|
case pkg.kind
|
|
of nkStrLit, nkRStrLit, nkTripleStrLit:
|
|
result = scriptableImport(pkg.strVal, sub, pkg.info)
|
|
of nkIdent:
|
|
result = scriptableImport(pkg.ident.s, sub, pkg.info)
|
|
else:
|
|
localError(pkg.info, "package name must be an identifier or string literal")
|
|
result = ""
|
|
|
|
proc getModuleName*(n: PNode): string =
|
|
# This returns a short relative module name without the nim extension
|
|
# e.g. like "system", "importer" or "somepath/module"
|
|
# The proc won't perform any checks that the path is actually valid
|
|
case n.kind
|
|
of nkStrLit, nkRStrLit, nkTripleStrLit:
|
|
try:
|
|
result = pathSubs(n.strVal, n.info.toFullPath().splitFile().dir)
|
|
except ValueError:
|
|
localError(n.info, "invalid path: " & n.strVal)
|
|
result = n.strVal
|
|
of nkIdent:
|
|
result = n.ident.s
|
|
of nkSym:
|
|
result = n.sym.name.s
|
|
of nkInfix:
|
|
let n0 = n[0]
|
|
let n1 = n[1]
|
|
if n0.kind == nkIdent and n0.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])
|
|
if n1.kind == nkPrefix and n1[0].kind == nkIdent and n1[0].ident.s == "$":
|
|
if n0.kind == nkIdent and n0.ident.s == "/":
|
|
result = lookupPackage(n1[1], n[2])
|
|
else:
|
|
localError(n.info, "only '/' supported with $package notation")
|
|
result = ""
|
|
else:
|
|
# hacky way to implement 'x / y /../ z':
|
|
result = getModuleName(n1)
|
|
result.add renderTree(n0, {renderNoComments})
|
|
result.add getModuleName(n[2])
|
|
of nkPrefix:
|
|
if n.sons[0].kind == nkIdent and n.sons[0].ident.s == "$":
|
|
result = lookupPackage(n[1], nil)
|
|
else:
|
|
# hacky way to implement 'x / y /../ z':
|
|
result = renderTree(n, {renderNoComments}).replace(" ")
|
|
of nkDotExpr:
|
|
result = renderTree(n, {renderNoComments}).replace(".", "/")
|
|
of nkImportAs:
|
|
result = getModuleName(n.sons[0])
|
|
else:
|
|
localError(n.info, errGenerated, "invalid module name: '$1'" % n.renderTree)
|
|
result = ""
|
|
|
|
proc checkModuleName*(n: PNode; doLocalError=true): int32 =
|
|
# This returns the full canonical path for a given module import
|
|
let modulename = n.getModuleName
|
|
let fullPath = findModule(modulename, n.info.toFullPath)
|
|
if fullPath.len == 0:
|
|
if doLocalError:
|
|
localError(n.info, errCannotOpenFile, modulename)
|
|
result = InvalidFileIDX
|
|
else:
|
|
result = fullPath.fileInfoIdx |