Make Nimble compatible with the upcoming compiler API changes (#500)
* Make Nimble compatible with the upcoming compiler API changes * make travis use nim-0.18.0 * make Nimble compile with older compiler versions * attempt to make tests green with Nim v0.18
This commit is contained in:
parent
8c57227f55
commit
3b177e278b
3 changed files with 107 additions and 49 deletions
|
|
@ -6,16 +6,16 @@ language: c
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- |
|
- |
|
||||||
wget https://nim-lang.org/download/nim-0.17.2.tar.xz
|
wget https://nim-lang.org/download/nim-0.18.0.tar.xz
|
||||||
tar -xf nim-0.17.2.tar.xz
|
tar -xf nim-0.18.0.tar.xz
|
||||||
cd nim-0.17.2
|
cd nim-0.18.0
|
||||||
sh build.sh
|
sh build.sh
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- set -e
|
- set -e
|
||||||
- set -x
|
- set -x
|
||||||
- export PATH=`pwd`/nim-0.17.2/bin:$PATH
|
- export PATH=`pwd`/nim-0.18.0/bin:$PATH
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- cd tests
|
- cd tests
|
||||||
|
|
|
||||||
|
|
@ -40,15 +40,26 @@ proc raiseVariableError(ident, typ: string) {.noinline.} =
|
||||||
|
|
||||||
proc isStrLit(n: PNode): bool = n.kind in {nkStrLit..nkTripleStrLit}
|
proc isStrLit(n: PNode): bool = n.kind in {nkStrLit..nkTripleStrLit}
|
||||||
|
|
||||||
proc getGlobal(ident: PSym): string =
|
when declared(NimCompilerApiVersion):
|
||||||
let n = vm.globalCtx.getGlobalValue(ident)
|
const finalApi = NimCompilerApiVersion >= 2
|
||||||
|
else:
|
||||||
|
const finalApi = false
|
||||||
|
|
||||||
|
proc getGlobal(g: ModuleGraph; ident: PSym): string =
|
||||||
|
when finalApi:
|
||||||
|
let n = vm.getGlobalValue(PCtx g.vm, ident)
|
||||||
|
else:
|
||||||
|
let n = vm.globalCtx.getGlobalValue(ident)
|
||||||
if n.isStrLit:
|
if n.isStrLit:
|
||||||
result = if n.strVal.isNil: "" else: n.strVal
|
result = if n.strVal.isNil: "" else: n.strVal
|
||||||
else:
|
else:
|
||||||
raiseVariableError(ident.name.s, "string")
|
raiseVariableError(ident.name.s, "string")
|
||||||
|
|
||||||
proc getGlobalAsSeq(ident: PSym): seq[string] =
|
proc getGlobalAsSeq(g: ModuleGraph; ident: PSym): seq[string] =
|
||||||
let n = vm.globalCtx.getGlobalValue(ident)
|
when finalApi:
|
||||||
|
let n = vm.getGlobalValue(PCtx g.vm, ident)
|
||||||
|
else:
|
||||||
|
let n = vm.globalCtx.getGlobalValue(ident)
|
||||||
result = @[]
|
result = @[]
|
||||||
if n.kind == nkBracket:
|
if n.kind == nkBracket:
|
||||||
for x in n:
|
for x in n:
|
||||||
|
|
@ -59,8 +70,11 @@ proc getGlobalAsSeq(ident: PSym): seq[string] =
|
||||||
else:
|
else:
|
||||||
raiseVariableError(ident.name.s, "seq[string]")
|
raiseVariableError(ident.name.s, "seq[string]")
|
||||||
|
|
||||||
proc extractRequires(ident: PSym, result: var seq[PkgTuple]) =
|
proc extractRequires(g: ModuleGraph; ident: PSym, result: var seq[PkgTuple]) =
|
||||||
let n = vm.globalCtx.getGlobalValue(ident)
|
when finalApi:
|
||||||
|
let n = vm.getGlobalValue(PCtx g.vm, ident)
|
||||||
|
else:
|
||||||
|
let n = vm.globalCtx.getGlobalValue(ident)
|
||||||
if n.kind == nkBracket:
|
if n.kind == nkBracket:
|
||||||
for x in n:
|
for x in n:
|
||||||
if x.kind == nkPar and x.len == 2 and x[0].isStrLit and x[1].isStrLit:
|
if x.kind == nkPar and x.len == 2 and x[0].isStrLit and x[1].isStrLit:
|
||||||
|
|
@ -268,14 +282,20 @@ proc getLibVersion(lib: string): Version =
|
||||||
else:
|
else:
|
||||||
return system.NimVersion.newVersion()
|
return system.NimVersion.newVersion()
|
||||||
|
|
||||||
when declared(ModuleGraph):
|
when finalApi:
|
||||||
|
var graph = newModuleGraph(identCache, newConfigRef())
|
||||||
|
|
||||||
|
elif declared(ModuleGraph):
|
||||||
var graph = newModuleGraph()
|
var graph = newModuleGraph()
|
||||||
|
|
||||||
proc execScript(scriptName: string, flags: Flags, options: Options): PSym =
|
proc execScript(scriptName: string, flags: Flags, options: Options): PSym =
|
||||||
## Executes the specified script. Returns the script's module symbol.
|
## Executes the specified script. Returns the script's module symbol.
|
||||||
##
|
##
|
||||||
## No clean up is performed and must be done manually!
|
## No clean up is performed and must be done manually!
|
||||||
graph = newModuleGraph(graph.config)
|
when finalApi:
|
||||||
|
graph = newModuleGraph(graph.cache, graph.config)
|
||||||
|
else:
|
||||||
|
graph = newModuleGraph(graph.config)
|
||||||
|
|
||||||
let conf = graph.config
|
let conf = graph.config
|
||||||
when declared(NimCompilerApiVersion):
|
when declared(NimCompilerApiVersion):
|
||||||
|
|
@ -353,15 +373,22 @@ proc execScript(scriptName: string, flags: Flags, options: Options): PSym =
|
||||||
|
|
||||||
when declared(NimCompilerApiVersion):
|
when declared(NimCompilerApiVersion):
|
||||||
initDefines(conf.symbols)
|
initDefines(conf.symbols)
|
||||||
loadConfigs(DefaultConfig, conf)
|
when NimCompilerApiVersion >= 2:
|
||||||
passes.gIncludeFile = includeModule
|
loadConfigs(DefaultConfig, graph.cache, conf)
|
||||||
passes.gImportModule = importModule
|
else:
|
||||||
|
loadConfigs(DefaultConfig, conf)
|
||||||
|
passes.gIncludeFile = includeModule
|
||||||
|
passes.gImportModule = importModule
|
||||||
|
|
||||||
defineSymbol(conf.symbols, "nimscript")
|
defineSymbol(conf.symbols, "nimscript")
|
||||||
defineSymbol(conf.symbols, "nimconfig")
|
defineSymbol(conf.symbols, "nimconfig")
|
||||||
defineSymbol(conf.symbols, "nimble")
|
defineSymbol(conf.symbols, "nimble")
|
||||||
registerPass(semPass)
|
when NimCompilerApiVersion >= 2:
|
||||||
registerPass(evalPass)
|
registerPass(graph, semPass)
|
||||||
|
registerPass(graph, evalPass)
|
||||||
|
else:
|
||||||
|
registerPass(semPass)
|
||||||
|
registerPass(evalPass)
|
||||||
|
|
||||||
conf.searchPaths.add(conf.libpath)
|
conf.searchPaths.add(conf.libpath)
|
||||||
else:
|
else:
|
||||||
|
|
@ -384,18 +411,31 @@ proc execScript(scriptName: string, flags: Flags, options: Options): PSym =
|
||||||
result = graph.makeModule(scriptName)
|
result = graph.makeModule(scriptName)
|
||||||
|
|
||||||
incl(result.flags, sfMainModule)
|
incl(result.flags, sfMainModule)
|
||||||
vm.globalCtx = setupVM(graph, result, scriptName, flags)
|
when finalApi:
|
||||||
|
graph.vm = setupVM(graph, result, scriptName, flags)
|
||||||
|
|
||||||
# Setup builtins defined in nimscriptapi.nim
|
# Setup builtins defined in nimscriptapi.nim
|
||||||
template cbApi(name, body) {.dirty.} =
|
template cbApi(name, body) {.dirty.} =
|
||||||
vm.globalCtx.registerCallback "nimscriptapi." & astToStr(name),
|
PCtx(graph.vm).registerCallback "nimscriptapi." & astToStr(name),
|
||||||
proc (a: VmArgs) =
|
proc (a: VmArgs) =
|
||||||
body
|
body
|
||||||
|
|
||||||
|
else:
|
||||||
|
vm.globalCtx = setupVM(graph, result, scriptName, flags)
|
||||||
|
|
||||||
|
# Setup builtins defined in nimscriptapi.nim
|
||||||
|
template cbApi(name, body) {.dirty.} =
|
||||||
|
vm.globalCtx.registerCallback "nimscriptapi." & astToStr(name),
|
||||||
|
proc (a: VmArgs) =
|
||||||
|
body
|
||||||
|
|
||||||
cbApi getPkgDir:
|
cbApi getPkgDir:
|
||||||
setResult(a, scriptName.splitFile.dir)
|
setResult(a, scriptName.splitFile.dir)
|
||||||
|
|
||||||
when declared(newIdentCache):
|
when finalApi:
|
||||||
|
graph.compileSystemModule()
|
||||||
|
graph.processModule(result, llStreamOpen(scriptName, fmRead))
|
||||||
|
elif declared(newIdentCache):
|
||||||
graph.compileSystemModule(identCache)
|
graph.compileSystemModule(identCache)
|
||||||
graph.processModule(result, llStreamOpen(scriptName, fmRead), nil, identCache)
|
graph.processModule(result, llStreamOpen(scriptName, fmRead), nil, identCache)
|
||||||
else:
|
else:
|
||||||
|
|
@ -417,11 +457,18 @@ proc cleanup() =
|
||||||
resetAllModulesHard()
|
resetAllModulesHard()
|
||||||
else:
|
else:
|
||||||
resetSystemArtifacts()
|
resetSystemArtifacts()
|
||||||
clearPasses()
|
when finalApi:
|
||||||
|
clearPasses(graph)
|
||||||
|
else:
|
||||||
|
clearPasses()
|
||||||
when declared(NimCompilerApiVersion):
|
when declared(NimCompilerApiVersion):
|
||||||
conf.errorMax = 1
|
conf.errorMax = 1
|
||||||
msgs.writeLnHook = nil
|
when NimCompilerApiVersion >= 2:
|
||||||
vm.globalCtx = nil
|
conf.writeLnHook = nil
|
||||||
|
graph.vm = nil
|
||||||
|
else:
|
||||||
|
msgs.writeLnHook = nil
|
||||||
|
vm.globalCtx = nil
|
||||||
initDefines(conf.symbols)
|
initDefines(conf.symbols)
|
||||||
else:
|
else:
|
||||||
msgs.gErrorMax = 1
|
msgs.gErrorMax = 1
|
||||||
|
|
@ -446,16 +493,21 @@ proc readPackageInfoFromNims*(scriptName: string, options: Options,
|
||||||
else: msgs.gErrorCounter
|
else: msgs.gErrorCounter
|
||||||
|
|
||||||
var previousMsg = ""
|
var previousMsg = ""
|
||||||
msgs.writeLnHook =
|
|
||||||
proc (output: string) =
|
proc writelnHook(output: string) =
|
||||||
# The error counter is incremented after the writeLnHook is invoked.
|
# The error counter is incremented after the writeLnHook is invoked.
|
||||||
if errCounter() > 0:
|
if errCounter() > 0:
|
||||||
raise newException(NimbleError, previousMsg)
|
raise newException(NimbleError, previousMsg)
|
||||||
elif previousMsg.len > 0:
|
elif previousMsg.len > 0:
|
||||||
display("Info", previousMsg, priority = MediumPriority)
|
display("Info", previousMsg, priority = MediumPriority)
|
||||||
if output.normalize.startsWith("error"):
|
if output.normalize.startsWith("error"):
|
||||||
raise newException(NimbleError, output)
|
raise newException(NimbleError, output)
|
||||||
previousMsg = output
|
previousMsg = output
|
||||||
|
|
||||||
|
when finalApi:
|
||||||
|
conf.writelnHook = writelnHook
|
||||||
|
else:
|
||||||
|
msgs.writeLnHook = writelnHook
|
||||||
|
|
||||||
when declared(NimCompilerApiVersion):
|
when declared(NimCompilerApiVersion):
|
||||||
conf.command = internalCmd
|
conf.command = internalCmd
|
||||||
|
|
@ -482,18 +534,18 @@ proc readPackageInfoFromNims*(scriptName: string, options: Options,
|
||||||
|
|
||||||
# Extract all the necessary fields populated by the nimscript file.
|
# Extract all the necessary fields populated by the nimscript file.
|
||||||
proc getSym(apiModule: PSym, ident: string): PSym =
|
proc getSym(apiModule: PSym, ident: string): PSym =
|
||||||
result = apiModule.tab.strTableGet(getIdent(ident))
|
result = apiModule.tab.strTableGet(getIdent(identCache, ident))
|
||||||
if result.isNil:
|
if result.isNil:
|
||||||
raise newException(NimbleError, "Ident not found: " & ident)
|
raise newException(NimbleError, "Ident not found: " & ident)
|
||||||
|
|
||||||
template trivialField(field) =
|
template trivialField(field) =
|
||||||
result.field = getGlobal(getSym(apiModule, astToStr field))
|
result.field = getGlobal(graph, getSym(apiModule, astToStr field))
|
||||||
|
|
||||||
template trivialFieldSeq(field) =
|
template trivialFieldSeq(field) =
|
||||||
result.field.add getGlobalAsSeq(getSym(apiModule, astToStr field))
|
result.field.add getGlobalAsSeq(graph, getSym(apiModule, astToStr field))
|
||||||
|
|
||||||
# keep reasonable default:
|
# keep reasonable default:
|
||||||
let name = getGlobal(apiModule.tab.strTableGet(getIdent"packageName"))
|
let name = getGlobal(graph, apiModule.tab.strTableGet(getIdent(identCache, "packageName")))
|
||||||
if name.len > 0: result.name = name
|
if name.len > 0: result.name = name
|
||||||
|
|
||||||
trivialField version
|
trivialField version
|
||||||
|
|
@ -510,13 +562,13 @@ proc readPackageInfoFromNims*(scriptName: string, options: Options,
|
||||||
trivialFieldSeq installExt
|
trivialFieldSeq installExt
|
||||||
trivialFieldSeq foreignDeps
|
trivialFieldSeq foreignDeps
|
||||||
|
|
||||||
extractRequires(getSym(apiModule, "requiresData"), result.requires)
|
extractRequires(graph, getSym(apiModule, "requiresData"), result.requires)
|
||||||
|
|
||||||
let binSeq = getGlobalAsSeq(getSym(apiModule, "bin"))
|
let binSeq = getGlobalAsSeq(graph, getSym(apiModule, "bin"))
|
||||||
for i in binSeq:
|
for i in binSeq:
|
||||||
result.bin.add(i.addFileExt(ExeExt))
|
result.bin.add(i.addFileExt(ExeExt))
|
||||||
|
|
||||||
let backend = getGlobal(getSym(apiModule, "backend"))
|
let backend = getGlobal(graph, getSym(apiModule, "backend"))
|
||||||
if backend.len == 0:
|
if backend.len == 0:
|
||||||
result.backend = "c"
|
result.backend = "c"
|
||||||
elif cmpIgnoreStyle(backend, "javascript") == 0:
|
elif cmpIgnoreStyle(backend, "javascript") == 0:
|
||||||
|
|
@ -556,12 +608,15 @@ proc execTask*(scriptName, taskName: string,
|
||||||
priority = HighPriority)
|
priority = HighPriority)
|
||||||
|
|
||||||
let thisModule = execScript(scriptName, result.flags, options)
|
let thisModule = execScript(scriptName, result.flags, options)
|
||||||
let prc = thisModule.tab.strTableGet(getIdent(taskName & "Task"))
|
let prc = thisModule.tab.strTableGet(getIdent(identCache, taskName & "Task"))
|
||||||
if prc.isNil:
|
if prc.isNil:
|
||||||
# Procedure not defined in the NimScript module.
|
# Procedure not defined in the NimScript module.
|
||||||
result.success = false
|
result.success = false
|
||||||
return
|
return
|
||||||
discard vm.globalCtx.execProc(prc, [])
|
when finalApi:
|
||||||
|
discard vm.execProc(PCtx(graph.vm), prc, [])
|
||||||
|
else:
|
||||||
|
discard vm.globalCtx.execProc(prc, [])
|
||||||
|
|
||||||
# Read the command, arguments and flags set by the executed task.
|
# Read the command, arguments and flags set by the executed task.
|
||||||
result.command = nimCommand()
|
result.command = nimCommand()
|
||||||
|
|
@ -590,13 +645,16 @@ proc execHook*(scriptName, actionName: string, before: bool,
|
||||||
|
|
||||||
let thisModule = execScript(scriptName, result.flags, options)
|
let thisModule = execScript(scriptName, result.flags, options)
|
||||||
# Explicitly execute the task procedure, instead of relying on hack.
|
# Explicitly execute the task procedure, instead of relying on hack.
|
||||||
let prc = thisModule.tab.strTableGet(getIdent(hookName))
|
let prc = thisModule.tab.strTableGet(getIdent(identCache, hookName))
|
||||||
if prc.isNil:
|
if prc.isNil:
|
||||||
# Procedure not defined in the NimScript module.
|
# Procedure not defined in the NimScript module.
|
||||||
result.success = false
|
result.success = false
|
||||||
cleanup()
|
cleanup()
|
||||||
return
|
return
|
||||||
let returnVal = vm.globalCtx.execProc(prc, [])
|
when finalApi:
|
||||||
|
let returnVal = vm.execProc(PCtx(graph.vm), prc, [])
|
||||||
|
else:
|
||||||
|
let returnVal = vm.globalCtx.execProc(prc, [])
|
||||||
case returnVal.kind
|
case returnVal.kind
|
||||||
of nkCharLit..nkUInt64Lit:
|
of nkCharLit..nkUInt64Lit:
|
||||||
result.retVal = returnVal.intVal == 1
|
result.retVal = returnVal.intVal == 1
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ proc changeRoot*(origRoot, newRoot, path: string): string =
|
||||||
## the trailing separator. This would cause this method to throw during package
|
## the trailing separator. This would cause this method to throw during package
|
||||||
## installation.
|
## installation.
|
||||||
if path.startsWith(origRoot) or path.samePaths(origRoot):
|
if path.startsWith(origRoot) or path.samePaths(origRoot):
|
||||||
return newRoot / path[origRoot.len .. path.len-1]
|
return newRoot / path.substr(origRoot.len, path.len-1)
|
||||||
else:
|
else:
|
||||||
raise newException(ValueError,
|
raise newException(ValueError,
|
||||||
"Cannot change root of path: Path does not begin with original root.")
|
"Cannot change root of path: Path does not begin with original root.")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue