diff options
author | Neelesh Chandola <neelesh.chandola@outlook.com> | 2018-12-14 09:34:46 +0530 |
---|---|---|
committer | Neelesh Chandola <neelesh.chandola@outlook.com> | 2018-12-14 09:34:46 +0530 |
commit | f233b2fe8b0659674f10def4365a1c13f9bdebb8 (patch) | |
tree | 2267489131177677c9502c66a19da9501638be8d /compiler | |
parent | 31cff752e0687b663d15ebfa71a57d5723c5b876 (diff) | |
parent | 5b39c7aca91c1d20eb81425cf8f3854876aed475 (diff) | |
download | Nim-f233b2fe8b0659674f10def4365a1c13f9bdebb8.tar.gz |
Merge remote-tracking branch 'upstream/devel' into better-error-message
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/cmdlinehelper.nim | 12 | ||||
-rw-r--r-- | compiler/extccomp.nim | 2 | ||||
-rw-r--r-- | compiler/pathutils.nim | 171 | ||||
-rw-r--r-- | compiler/semstmts.nim | 4 | ||||
-rw-r--r-- | compiler/semtypes.nim | 4 | ||||
-rw-r--r-- | compiler/transf.nim | 5 |
6 files changed, 33 insertions, 165 deletions
diff --git a/compiler/cmdlinehelper.nim b/compiler/cmdlinehelper.nim index 8bd073314..9fbf4a0b0 100644 --- a/compiler/cmdlinehelper.nim +++ b/compiler/cmdlinehelper.nim @@ -48,6 +48,15 @@ proc loadConfigsAndRunMainCommand*(self: NimProg, cache: IdentCache; conf: Confi if self.suggestMode: conf.command = "nimsuggest" + # These defines/options should not be enabled while processing nimscript + # bug #4446, #9420, #8991, #9589, #9153 + undefSymbol(conf.symbols, "profiler") + undefSymbol(conf.symbols, "memProfiler") + undefSymbol(conf.symbols, "nodejs") + + # bug #9120 + conf.globalOptions.excl(optTaintMode) + proc runNimScriptIfExists(path: AbsoluteFile)= if fileExists(path): runNimScript(cache, path, freshDefines = false, conf) @@ -79,6 +88,9 @@ proc loadConfigsAndRunMainCommand*(self: NimProg, cache: IdentCache; conf: Confi # 'nimsuggest foo.nims' means to just auto-complete the NimScript file discard + # Reload configuration from .cfg file + loadConfigs(DefaultConfig, cache, conf) + # now process command line arguments again, because some options in the # command line can overwite the config file's settings extccomp.initVars(conf) diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index 4b9e1c6fe..23f723e29 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -780,7 +780,7 @@ proc linkViaResponseFile(conf: ConfigRef; cmd: string) = let linkerArgs = conf.projectName & "_" & "linkerArgs.txt" let args = cmd.substr(i) # GCC's response files don't support backslashes. Junk. - if conf.cCompiler == ccGcc: + if conf.cCompiler == ccGcc or conf.cCompiler == ccCLang: writeFile(linkerArgs, args.replace('\\', '/')) else: writeFile(linkerArgs, args) diff --git a/compiler/pathutils.nim b/compiler/pathutils.nim index 703467bc4..80c479898 100644 --- a/compiler/pathutils.nim +++ b/compiler/pathutils.nim @@ -9,9 +9,8 @@ ## Path handling utilities for Nim. Strictly typed code in order ## to avoid the never ending time sink in getting path handling right. -## Might be a candidate for the stdlib later. -import os, strutils +import os, strutils, pathnorm type AbsoluteFile* = distinct string @@ -45,130 +44,9 @@ proc cmpPaths*(x, y: AbsoluteDir): int {.borrow.} proc createDir*(x: AbsoluteDir) {.borrow.} -type - PathIter = object - i, prev: int - notFirst: bool - -proc hasNext(it: PathIter; x: string): bool = - it.i < x.len - -proc next(it: var PathIter; x: string): (int, int) = - it.prev = it.i - if not it.notFirst and x[it.i] in {DirSep, AltSep}: - # absolute path: - inc it.i - else: - while it.i < x.len and x[it.i] notin {DirSep, AltSep}: inc it.i - if it.i > it.prev: - result = (it.prev, it.i-1) - elif hasNext(it, x): - result = next(it, x) - - # skip all separators: - while it.i < x.len and x[it.i] in {DirSep, AltSep}: inc it.i - it.notFirst = true - -iterator dirs(x: string): (int, int) = - var it: PathIter - while hasNext(it, x): yield next(it, x) - -proc isDot(x: string; bounds: (int, int)): bool = - bounds[1] == bounds[0] and x[bounds[0]] == '.' - -proc isDotDot(x: string; bounds: (int, int)): bool = - bounds[1] == bounds[0] + 1 and x[bounds[0]] == '.' and x[bounds[0]+1] == '.' - -proc isSlash(x: string; bounds: (int, int)): bool = - bounds[1] == bounds[0] and x[bounds[0]] in {DirSep, AltSep} - -const canonDirSep = when isMainModule: '/' else: DirSep - -proc canon(x: string; result: var string; state: var int) = - # state: 0th bit set if isAbsolute path. Other bits count - # the number of path components. - for b in dirs(x): - if (state shr 1 == 0) and isSlash(x, b): - result.add canonDirSep - state = state or 1 - elif result.len > (state and 1) and isDotDot(x, b): - var d = result.len - # f/.. - while (d-1) > (state and 1) and result[d-1] notin {DirSep, AltSep}: - dec d - if d > 0: setLen(result, d-1) - elif isDot(x, b): - discard "discard the dot" - elif b[1] >= b[0]: - if result.len > 0 and result[^1] notin {DirSep, AltSep}: - result.add canonDirSep - result.add substr(x, b[0], b[1]) - inc state, 2 - -proc canon(x: string): string = - # - Turn multiple slashes into single slashes. - # - Resolve '/foo/../bar' to '/bar'. - # - Remove './' from the path. - result = newStringOfCap(x.len) - var state = 0 - canon(x, result, state) - -when FileSystemCaseSensitive: - template `!=?`(a, b: char): bool = toLowerAscii(a) != toLowerAscii(b) -else: - template `!=?`(a, b: char): bool = a != b - -proc relativeTo(full, base: string; sep = canonDirSep): string = - if full.len == 0: return "" - var f, b: PathIter - var ff = (0, -1) - var bb = (0, -1) # (int, int) - result = newStringOfCap(full.len) - # skip the common prefix: - while f.hasNext(full) and b.hasNext(base): - ff = next(f, full) - bb = next(b, base) - let diff = ff[1] - ff[0] - if diff != bb[1] - bb[0]: break - var same = true - for i in 0..diff: - if full[i + ff[0]] !=? base[i + bb[0]]: - same = false - break - if not same: break - ff = (0, -1) - bb = (0, -1) - # for i in 0..diff: - # result.add base[i + bb[0]] - - # /foo/bar/xxx/ -- base - # /foo/bar/baz -- full path - # ../baz - # every directory that is in 'base', needs to add '..' - while true: - if bb[1] >= bb[0]: - if result.len > 0 and result[^1] != sep: - result.add sep - result.add ".." - if not b.hasNext(base): break - bb = b.next(base) - - # add the rest of 'full': - while true: - if ff[1] >= ff[0]: - if result.len > 0 and result[^1] != sep: - result.add sep - for i in 0..ff[1] - ff[0]: - result.add full[i + ff[0]] - if not f.hasNext(full): break - ff = f.next(full) - when true: - proc eqImpl(x, y: string): bool = - when FileSystemCaseSensitive: - result = cmpIgnoreCase(canon x, canon y) == 0 - else: - result = canon(x) == canon(y) + proc eqImpl(x, y: string): bool {.inline.} = + result = cmpPaths(x, y) == 0 proc `==`*(x, y: AbsoluteFile): bool = eqImpl(x.string, y.string) proc `==`*(x, y: AbsoluteDir): bool = eqImpl(x.string, y.string) @@ -180,20 +58,20 @@ when true: assert(not isAbsolute(f.string)) result = AbsoluteFile newStringOfCap(base.string.len + f.string.len) var state = 0 - canon(base.string, result.string, state) - canon(f.string, result.string, state) + addNormalizePath(base.string, result.string, state) + addNormalizePath(f.string, result.string, state) 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 - canon(base.string, result.string, state) - canon(f.string, result.string, state) + addNormalizePath(base.string, result.string, state) + addNormalizePath(f.string, result.string, state) proc relativeTo*(fullPath: AbsoluteFile, baseFilename: AbsoluteDir; - sep = canonDirSep): RelativeFile = - RelativeFile(relativeTo(fullPath.string, baseFilename.string, sep)) + sep = DirSep): RelativeFile = + RelativeFile(relativePath(fullPath.string, baseFilename.string, sep)) proc toAbsolute*(file: string; base: AbsoluteDir): AbsoluteFile = if isAbsolute(file): result = AbsoluteFile(file) @@ -208,37 +86,8 @@ when true: proc writeFile*(x: AbsoluteFile; content: string) {.borrow.} when isMainModule: - doAssert canon"/foo/../bar" == "/bar" - doAssert canon"foo/../bar" == "bar" - - doAssert canon"/f/../bar///" == "/bar" - doAssert canon"f/..////bar" == "bar" - - doAssert canon"../bar" == "../bar" - doAssert canon"/../bar" == "/../bar" - - doAssert canon("foo/../../bar/") == "../bar" - doAssert canon("./bla/blob/") == "bla/blob" - doAssert canon(".hiddenFile") == ".hiddenFile" - doAssert canon("./bla/../../blob/./zoo.nim") == "../blob/zoo.nim" - - doAssert canon("C:/file/to/this/long") == "C:/file/to/this/long" - doAssert canon("") == "" - doAssert canon("foobar") == "foobar" - doAssert canon("f/////////") == "f" - - doAssert relativeTo("/foo/bar//baz.nim", "/foo") == "bar/baz.nim" - - doAssert relativeTo("/Users/me/bar/z.nim", "/Users/other/bad") == "../../me/bar/z.nim" - - doAssert relativeTo("/Users/me/bar/z.nim", "/Users/other") == "../me/bar/z.nim" - doAssert relativeTo("/Users///me/bar//z.nim", "//Users/") == "me/bar/z.nim" - doAssert relativeTo("/Users/me/bar/z.nim", "/Users/me") == "bar/z.nim" - doAssert relativeTo("", "/users/moo") == "" - doAssert relativeTo("foo", "") == "foo" - doAssert AbsoluteDir"/Users/me///" / RelativeFile"z.nim" == AbsoluteFile"/Users/me/z.nim" - doAssert relativeTo("/foo/bar.nim", "/foo/") == "bar.nim" + doAssert relativePath("/foo/bar.nim", "/foo/", '/') == "bar.nim" when isMainModule and defined(windows): let nasty = string(AbsoluteDir(r"C:\Users\rumpf\projects\nim\tests\nimble\nimbleDir\linkedPkgs\pkgB-#head\../../simplePkgs/pkgB-#head/") / RelativeFile"pkgA/module.nim") diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index aec03b492..5be57f614 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -807,11 +807,13 @@ proc semCase(c: PContext, n: PNode; flags: TExprFlags): PNode = typ = commonType(typ, x.sons[1]) closeScope(c) of nkElse: - chckCovered = false checkSonsLen(x, 1, c.config) x.sons[0] = semExprBranchScope(c, x.sons[0]) typ = commonType(typ, x.sons[0]) hasElse = true + if chckCovered and covered == toCover(c, n.sons[0].typ): + localError(c.config, x.info, "invalid else, all cases are already covered") + chckCovered = false else: illFormedAst(x, c.config) if chckCovered: diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 97ee062d1..2ca10ada2 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -90,7 +90,7 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = if sonsLen(v) == 2: strVal = v.sons[1] # second tuple part is the string value if skipTypes(strVal.typ, abstractInst).kind in {tyString, tyCString}: - if not isOrdinalType(v.sons[0].typ): + if not isOrdinalType(v.sons[0].typ, allowEnumWithHoles=true): localError(c.config, v.sons[0].info, errOrdinalTypeExpected & "; given: " & typeToString(v.sons[0].typ, preferDesc)) x = getOrdValue(v.sons[0]) # first tuple part is the ordinal else: @@ -101,7 +101,7 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = strVal = v x = counter else: - if not isOrdinalType(v.typ): + if not isOrdinalType(v.typ, allowEnumWithHoles=true): localError(c.config, v.info, errOrdinalTypeExpected & "; given: " & typeToString(v.typ, preferDesc)) x = getOrdValue(v) if i != 1: diff --git a/compiler/transf.nim b/compiler/transf.nim index 7b2979dea..82be4158f 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -368,6 +368,11 @@ proc transformYield(c: PTransf, n: PNode): PTransNode = else: # we need to introduce new local variables: add(result, introduceNewLocalVars(c, c.transCon.forLoopBody.PNode)) + if result.len > 0: + var changeNode = PNode(result[0]) + changeNode.info = c.transCon.forStmt.info + for i, child in changeNode: + child.info = changeNode.info proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PTransNode = result = transformSons(c, n) |