From dc830d8faf6067c4948e12e7dc4d6aecd9beb640 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Sat, 11 Jan 2020 15:00:06 -0800 Subject: [PATCH 1/8] successX now correctly shows html output for nim doc --- compiler/docgen.nim | 5 ++++- compiler/main.nim | 9 ++++++--- compiler/options.nim | 7 ++++++- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/compiler/docgen.nim b/compiler/docgen.nim index e4325aaafde0..8c57088c36a5 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -40,7 +40,7 @@ type exampleCounter: int emitted: IntSet # we need to track which symbols have been emitted # already. See bug #3655 - destFile*: AbsoluteFile + destFile*: AbsoluteFile # that's a lie... thisDir*: AbsoluteDir examples: string @@ -1072,6 +1072,8 @@ proc writeOutput*(d: PDoc, useWarning = false) = if not writeRope(content, outfile): rawMessage(d.conf, if useWarning: warnCannotOpenFile else: errCannotOpenFile, outfile.string) + # for some reason, outfile is relative, violating its type contract + d.conf.outFileAlt = outfile.`$`.absolutePath.AbsoluteFile proc writeOutputJson*(d: PDoc, useWarning = false) = runAllExamples(d) @@ -1089,6 +1091,7 @@ proc writeOutputJson*(d: PDoc, useWarning = false) = if open(f, d.destFile.string, fmWrite): write(f, $content) close(f) + d.conf.outFileAlt = d.destFile else: localError(d.conf, newLineInfo(d.conf, AbsoluteFile d.filename, -1, -1), warnUser, "unable to open file \"" & d.destFile.string & diff --git a/compiler/main.nim b/compiler/main.nim index 7008702411fa..0c3d88f0ce4e 100644 --- a/compiler/main.nim +++ b/compiler/main.nim @@ -19,7 +19,7 @@ import cgen, json, nversion, platform, nimconf, passaux, depends, vm, idgen, modules, - modulegraphs, tables, rod, lineinfos, pathutils + modulegraphs, tables, rod, lineinfos, pathutils, os when not defined(leanCompiler): import jsgen, docgen, docgen2 @@ -363,8 +363,11 @@ proc mainCommand*(graph: ModuleGraph) = elif isDefined(conf, "release"): "Release" else: "Debug" let sec = formatFloat(epochTime() - conf.lastCmdTime, ffDecimal, 3) - let project = if optListFullPaths in conf.globalOptions: $conf.projectFull else: $conf.projectName - let output = if optListFullPaths in conf.globalOptions: $conf.getOutFileFull else: $conf.outFile + template postprocess(path): untyped = + if optListFullPaths in conf.globalOptions: $path + else: path.`$`.lastPathPart + let project = conf.projectFull.postprocess + let output = conf.getOutFileFull.postprocess rawMessage(conf, hintSuccessX, [ "loc", loc, "sec", sec, diff --git a/compiler/options.nim b/compiler/options.nim index 9a0fa45b0633..084d668b02d9 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -244,6 +244,7 @@ type searchPaths*: seq[AbsoluteDir] lazyPaths*: seq[AbsoluteDir] outFile*: RelativeFile + outFileAlt*: AbsoluteFile ## eg html produced by `nim doc` outDir*: AbsoluteDir prefixDir*, libpath*, nimcacheDir*: AbsoluteDir dllOverrides, moduleOverrides*, cfileSpecificOptions*: StringTableRef @@ -284,7 +285,11 @@ type severity: Severity) {.closure, gcsafe.} cppCustomNamespace*: string -proc getOutFileFull*(a: ConfigRef): AbsoluteFile = a.outDir / a.outFile +proc getOutFileFull*(a: ConfigRef): AbsoluteFile = + if a.outFile.`$`.len > 0: + result = a.outDir / a.outFile + else: + result = a.outFileAlt proc hcrOn*(conf: ConfigRef): bool = return optHotCodeReloading in conf.globalOptions From 945c24f4d9e2e742cfbd1e22ad00fbeedac9b6d5 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Sun, 12 Jan 2020 12:48:32 -0800 Subject: [PATCH 2/8] _ --- compiler/docgen.nim | 2 +- compiler/pathutils.nim | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 8c57088c36a5..586ebc58be2e 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -40,7 +40,7 @@ type exampleCounter: int emitted: IntSet # we need to track which symbols have been emitted # already. See bug #3655 - destFile*: AbsoluteFile # that's a lie... + destFile*: AbsoluteFile thisDir*: AbsoluteDir examples: string diff --git a/compiler/pathutils.nim b/compiler/pathutils.nim index b73942a21654..ce5cc023af4d 100644 --- a/compiler/pathutils.nim +++ b/compiler/pathutils.nim @@ -54,21 +54,21 @@ when true: proc `==`*[T: AnyPath](x, y: T): bool = eqImpl(x.string, y.string) - proc `/`*(base: AbsoluteDir; f: RelativeFile): AbsoluteFile = + proc joinPathImpl[T](base: AbsoluteDir; f: T, T2: typedesc): T2 = + var base = base + if base.isEmpty: base = getCurrentDir().AbsoluteDir #assert isAbsolute(base.string) assert(not isAbsolute(f.string)) - result = AbsoluteFile newStringOfCap(base.string.len + f.string.len) + result = T2 newStringOfCap(base.string.len + f.string.len) var state = 0 addNormalizePath(base.string, result.string, state) addNormalizePath(f.string, result.string, state) + proc `/`*(base: AbsoluteDir; f: RelativeFile): AbsoluteFile = + joinPathImpl(base, f, AbsoluteFile) + proc `/`*(base: AbsoluteDir; f: RelativeDir): AbsoluteDir = - #assert isAbsolute(base.string) - assert(not isAbsolute(f.string)) - result = AbsoluteDir newStringOfCap(base.string.len + f.string.len) - var state = 0 - addNormalizePath(base.string, result.string, state) - addNormalizePath(f.string, result.string, state) + joinPathImpl(base, f, AbsoluteDir) proc relativeTo*(fullPath: AbsoluteFile, baseFilename: AbsoluteDir; sep = DirSep): RelativeFile = From dfd60237f9986105b9999b798dded7bdc8204a4d Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Sun, 12 Jan 2020 12:51:43 -0800 Subject: [PATCH 3/8] fix #13121 --- compiler/docgen.nim | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 586ebc58be2e..2fd93550c19d 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -1066,14 +1066,13 @@ proc writeOutput*(d: PDoc, useWarning = false) = if optStdout in d.conf.globalOptions: writeRope(stdout, content) else: - template outfile: untyped = d.destFile + let outfile = d.destFile #let outfile = getOutFile2(d.conf, shortenDir(d.conf, filename), outExt, "htmldocs") createDir(outfile.splitFile.dir) if not writeRope(content, outfile): rawMessage(d.conf, if useWarning: warnCannotOpenFile else: errCannotOpenFile, outfile.string) - # for some reason, outfile is relative, violating its type contract - d.conf.outFileAlt = outfile.`$`.absolutePath.AbsoluteFile + d.conf.outFileAlt = outfile proc writeOutputJson*(d: PDoc, useWarning = false) = runAllExamples(d) From 581bf804e2e29518722870a7c1ef868c8d4778fa Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Sun, 12 Jan 2020 12:52:44 -0800 Subject: [PATCH 4/8] fixup hintSuccessX to be less weird --- compiler/lineinfos.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/lineinfos.nim b/compiler/lineinfos.nim index c0826bb5c69e..b5742e669eb8 100644 --- a/compiler/lineinfos.nim +++ b/compiler/lineinfos.nim @@ -98,7 +98,7 @@ const warnUser: "$1", hintSuccess: "operation successful: $#", # keep in sync with `pegSuccess` see testament.nim - hintSuccessX: "$loc LOC; $sec sec; $mem; $build build; $project proj; $output out", + hintSuccessX: "$loc LOC; $sec sec; $mem; $build build; proj: $project; out: $output", hintCC: "CC: \'$1\'", # unused hintLineTooLong: "line too long", hintXDeclaredButNotUsed: "'$1' is declared but not used", From 0b27ab3b95a45db8ad2e716b807834ad88f84412 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 13 Jan 2020 13:27:18 -0800 Subject: [PATCH 5/8] remove outFileAlt --- compiler/docgen.nim | 4 ++-- compiler/main.nim | 10 +++++----- compiler/options.nim | 7 +------ compiler/pathutils.nim | 8 ++++++++ 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 2fd93550c19d..9e547ca9bfee 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -1072,7 +1072,7 @@ proc writeOutput*(d: PDoc, useWarning = false) = if not writeRope(content, outfile): rawMessage(d.conf, if useWarning: warnCannotOpenFile else: errCannotOpenFile, outfile.string) - d.conf.outFileAlt = outfile + d.conf.outFile = outfile.lastPathPart proc writeOutputJson*(d: PDoc, useWarning = false) = runAllExamples(d) @@ -1090,7 +1090,7 @@ proc writeOutputJson*(d: PDoc, useWarning = false) = if open(f, d.destFile.string, fmWrite): write(f, $content) close(f) - d.conf.outFileAlt = d.destFile + d.conf.outFile = d.destFile.lastPathPart else: localError(d.conf, newLineInfo(d.conf, AbsoluteFile d.filename, -1, -1), warnUser, "unable to open file \"" & d.destFile.string & diff --git a/compiler/main.nim b/compiler/main.nim index 0c3d88f0ce4e..55b6c0dac09d 100644 --- a/compiler/main.nim +++ b/compiler/main.nim @@ -19,7 +19,7 @@ import cgen, json, nversion, platform, nimconf, passaux, depends, vm, idgen, modules, - modulegraphs, tables, rod, lineinfos, pathutils, os + modulegraphs, tables, rod, lineinfos, pathutils when not defined(leanCompiler): import jsgen, docgen, docgen2 @@ -363,11 +363,11 @@ proc mainCommand*(graph: ModuleGraph) = elif isDefined(conf, "release"): "Release" else: "Debug" let sec = formatFloat(epochTime() - conf.lastCmdTime, ffDecimal, 3) - template postprocess(path): untyped = + template displayPath(path): untyped = if optListFullPaths in conf.globalOptions: $path - else: path.`$`.lastPathPart - let project = conf.projectFull.postprocess - let output = conf.getOutFileFull.postprocess + else: $path.lastPathPart + let project = conf.projectFull.displayPath + let output = conf.getOutFileFull.displayPath rawMessage(conf, hintSuccessX, [ "loc", loc, "sec", sec, diff --git a/compiler/options.nim b/compiler/options.nim index 084d668b02d9..9a0fa45b0633 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -244,7 +244,6 @@ type searchPaths*: seq[AbsoluteDir] lazyPaths*: seq[AbsoluteDir] outFile*: RelativeFile - outFileAlt*: AbsoluteFile ## eg html produced by `nim doc` outDir*: AbsoluteDir prefixDir*, libpath*, nimcacheDir*: AbsoluteDir dllOverrides, moduleOverrides*, cfileSpecificOptions*: StringTableRef @@ -285,11 +284,7 @@ type severity: Severity) {.closure, gcsafe.} cppCustomNamespace*: string -proc getOutFileFull*(a: ConfigRef): AbsoluteFile = - if a.outFile.`$`.len > 0: - result = a.outDir / a.outFile - else: - result = a.outFileAlt +proc getOutFileFull*(a: ConfigRef): AbsoluteFile = a.outDir / a.outFile proc hcrOn*(conf: ConfigRef): bool = return optHotCodeReloading in conf.globalOptions diff --git a/compiler/pathutils.nim b/compiler/pathutils.nim index ce5cc023af4d..16f75482942e 100644 --- a/compiler/pathutils.nim +++ b/compiler/pathutils.nim @@ -26,6 +26,14 @@ proc copyFile*(source, dest: AbsoluteFile) = proc removeFile*(x: AbsoluteFile) {.borrow.} +template toRelative(x: typedesc[AnyPath]): typedesc = + when x is AbsoluteFile | RelativeFile: RelativeFile else: RelativeDir + +proc lastPathPart*(x: AnyPath): auto = + ## analog to os.lastPathPart + type T2 = toRelative(type(x)) + x.string.lastPathPart.T2 + proc splitFile*(x: AbsoluteFile): tuple[dir: AbsoluteDir, name, ext: string] = let (a, b, c) = splitFile(x.string) result = (dir: AbsoluteDir(a), name: b, ext: c) From a91792c0c79369c59816a3460c10be97f3847bc2 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 13 Jan 2020 14:24:16 -0800 Subject: [PATCH 6/8] address comment --- compiler/docgen.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 9e547ca9bfee..0cc6a2def31c 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -1066,7 +1066,7 @@ proc writeOutput*(d: PDoc, useWarning = false) = if optStdout in d.conf.globalOptions: writeRope(stdout, content) else: - let outfile = d.destFile + template outfile: untyped = d.destFile #let outfile = getOutFile2(d.conf, shortenDir(d.conf, filename), outExt, "htmldocs") createDir(outfile.splitFile.dir) if not writeRope(content, outfile): From 28106542537c18b4b6feda99a7d7e5c50bac2834 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Tue, 14 Jan 2020 14:57:06 -0800 Subject: [PATCH 7/8] bugfix: use absOutFile instead of getOutFileFull (because of foo.out special case) --- compiler/docgen.nim | 4 ++-- compiler/main.nim | 8 +++----- compiler/options.nim | 2 -- compiler/pathutils.nim | 30 +++++++++++++----------------- 4 files changed, 18 insertions(+), 26 deletions(-) diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 0cc6a2def31c..a09f54c16517 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -1072,7 +1072,7 @@ proc writeOutput*(d: PDoc, useWarning = false) = if not writeRope(content, outfile): rawMessage(d.conf, if useWarning: warnCannotOpenFile else: errCannotOpenFile, outfile.string) - d.conf.outFile = outfile.lastPathPart + d.conf.outFile = outfile.extractFilename.RelativeFile proc writeOutputJson*(d: PDoc, useWarning = false) = runAllExamples(d) @@ -1090,7 +1090,7 @@ proc writeOutputJson*(d: PDoc, useWarning = false) = if open(f, d.destFile.string, fmWrite): write(f, $content) close(f) - d.conf.outFile = d.destFile.lastPathPart + d.conf.outFile = d.destFile.extractFilename.RelativeFile else: localError(d.conf, newLineInfo(d.conf, AbsoluteFile d.filename, -1, -1), warnUser, "unable to open file \"" & d.destFile.string & diff --git a/compiler/main.nim b/compiler/main.nim index 55b6c0dac09d..3cafe1f2c018 100644 --- a/compiler/main.nim +++ b/compiler/main.nim @@ -363,11 +363,9 @@ proc mainCommand*(graph: ModuleGraph) = elif isDefined(conf, "release"): "Release" else: "Debug" let sec = formatFloat(epochTime() - conf.lastCmdTime, ffDecimal, 3) - template displayPath(path): untyped = - if optListFullPaths in conf.globalOptions: $path - else: $path.lastPathPart - let project = conf.projectFull.displayPath - let output = conf.getOutFileFull.displayPath + let project = if optListFullPaths in conf.globalOptions: $conf.projectFull else: $conf.projectName + var output = $conf.absOutFile + if optListFullPaths notin conf.globalOptions: output = output.AbsoluteFile.extractFilename rawMessage(conf, hintSuccessX, [ "loc", loc, "sec", sec, diff --git a/compiler/options.nim b/compiler/options.nim index 9a0fa45b0633..9c17ea1e6d83 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -284,8 +284,6 @@ type severity: Severity) {.closure, gcsafe.} cppCustomNamespace*: string -proc getOutFileFull*(a: ConfigRef): AbsoluteFile = a.outDir / a.outFile - proc hcrOn*(conf: ConfigRef): bool = return optHotCodeReloading in conf.globalOptions template depConfigFields*(fn) {.dirty.} = diff --git a/compiler/pathutils.nim b/compiler/pathutils.nim index 16f75482942e..9ef43e3047e0 100644 --- a/compiler/pathutils.nim +++ b/compiler/pathutils.nim @@ -26,14 +26,6 @@ proc copyFile*(source, dest: AbsoluteFile) = proc removeFile*(x: AbsoluteFile) {.borrow.} -template toRelative(x: typedesc[AnyPath]): typedesc = - when x is AbsoluteFile | RelativeFile: RelativeFile else: RelativeDir - -proc lastPathPart*(x: AnyPath): auto = - ## analog to os.lastPathPart - type T2 = toRelative(type(x)) - x.string.lastPathPart.T2 - proc splitFile*(x: AbsoluteFile): tuple[dir: AbsoluteDir, name, ext: string] = let (a, b, c) = splitFile(x.string) result = (dir: AbsoluteDir(a), name: b, ext: c) @@ -62,21 +54,25 @@ when true: proc `==`*[T: AnyPath](x, y: T): bool = eqImpl(x.string, y.string) - proc joinPathImpl[T](base: AbsoluteDir; f: T, T2: typedesc): T2 = - var base = base - if base.isEmpty: base = getCurrentDir().AbsoluteDir - #assert isAbsolute(base.string) + template checkValid(base: AbsoluteDir) = + # empty paths should not mean `cwd` + doAssert isAbsolute(base.string), base.string + + proc `/`*(base: AbsoluteDir; f: RelativeFile): AbsoluteFile = + checkValid(base) assert(not isAbsolute(f.string)) - result = T2 newStringOfCap(base.string.len + f.string.len) + result = AbsoluteFile newStringOfCap(base.string.len + f.string.len) var state = 0 addNormalizePath(base.string, result.string, state) addNormalizePath(f.string, result.string, state) - proc `/`*(base: AbsoluteDir; f: RelativeFile): AbsoluteFile = - joinPathImpl(base, f, AbsoluteFile) - proc `/`*(base: AbsoluteDir; f: RelativeDir): AbsoluteDir = - joinPathImpl(base, f, AbsoluteDir) + checkValid(base) + assert(not isAbsolute(f.string)) + result = AbsoluteDir newStringOfCap(base.string.len + f.string.len) + var state = 0 + addNormalizePath(base.string, result.string, state) + addNormalizePath(f.string, result.string, state) proc relativeTo*(fullPath: AbsoluteFile, baseFilename: AbsoluteDir; sep = DirSep): RelativeFile = From d5ccef7d576f0ea952de352b5908a121bdff2f83 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Tue, 14 Jan 2020 15:28:32 -0800 Subject: [PATCH 8/8] fixup --- compiler/pathutils.nim | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/compiler/pathutils.nim b/compiler/pathutils.nim index 9ef43e3047e0..e3dd69628856 100644 --- a/compiler/pathutils.nim +++ b/compiler/pathutils.nim @@ -54,12 +54,19 @@ when true: proc `==`*[T: AnyPath](x, y: T): bool = eqImpl(x.string, y.string) - template checkValid(base: AbsoluteDir) = - # empty paths should not mean `cwd` - doAssert isAbsolute(base.string), base.string + template postProcessBase(base: AbsoluteDir): untyped = + # xxx: as argued here https://github.com/nim-lang/Nim/pull/10018#issuecomment-448192956 + # empty paths should not mean `cwd` so the correct behavior would be to throw + # here and make sure `outDir` is always correctly initialized; for now + # we simply preserve pre-existing external semantics and treat it as `cwd` + when false: + doAssert isAbsolute(base.string), base.string + base + else: + if base.isEmpty: getCurrentDir().AbsoluteDir else: base proc `/`*(base: AbsoluteDir; f: RelativeFile): AbsoluteFile = - checkValid(base) + let base = postProcessBase(base) assert(not isAbsolute(f.string)) result = AbsoluteFile newStringOfCap(base.string.len + f.string.len) var state = 0 @@ -67,7 +74,7 @@ when true: addNormalizePath(f.string, result.string, state) proc `/`*(base: AbsoluteDir; f: RelativeDir): AbsoluteDir = - checkValid(base) + let base = postProcessBase(base) assert(not isAbsolute(f.string)) result = AbsoluteDir newStringOfCap(base.string.len + f.string.len) var state = 0