cleaned up os.nim; docgen improvements

This commit is contained in:
Araq 2014-12-21 14:28:46 +01:00
commit 24e66e04fa
7 changed files with 54 additions and 33 deletions

View file

@ -357,11 +357,11 @@ proc processPush(c: PContext, n: PNode, start: int) =
append(c.optionStack, x) append(c.optionStack, x)
for i in countup(start, sonsLen(n) - 1): for i in countup(start, sonsLen(n) - 1):
if processOption(c, n.sons[i]): if processOption(c, n.sons[i]):
# simply store it somehwere: # simply store it somewhere:
if x.otherPragmas.isNil: if x.otherPragmas.isNil:
x.otherPragmas = newNodeI(nkPragma, n.info) x.otherPragmas = newNodeI(nkPragma, n.info)
x.otherPragmas.add n.sons[i] x.otherPragmas.add n.sons[i]
#LocalError(n.info, errOptionExpected) #localError(n.info, errOptionExpected)
proc processPop(c: PContext, n: PNode) = proc processPop(c: PContext, n: PNode) =
if c.optionStack.counter <= 1: if c.optionStack.counter <= 1:

View file

@ -34,6 +34,7 @@ type
comStack*: seq[PNode] # comment stack comStack*: seq[PNode] # comment stack
flags*: TRenderFlags flags*: TRenderFlags
checkAnon: bool # we're in a context that can contain sfAnon checkAnon: bool # we're in a context that can contain sfAnon
inPragma: int
proc renderModule*(n: PNode, filename: string, renderFlags: TRenderFlags = {}) proc renderModule*(n: PNode, filename: string, renderFlags: TRenderFlags = {})
@ -1186,10 +1187,15 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
gsub(g, n.sons[0]) gsub(g, n.sons[0])
of nkPragma: of nkPragma:
if renderNoPragmas notin g.flags: if renderNoPragmas notin g.flags:
if g.inPragma <= 0:
inc g.inPragma
put(g, tkSpaces, Space) put(g, tkSpaces, Space)
put(g, tkCurlyDotLe, "{.") put(g, tkCurlyDotLe, "{.")
gcomma(g, n, emptyContext) gcomma(g, n, emptyContext)
put(g, tkCurlyDotRi, ".}") put(g, tkCurlyDotRi, ".}")
dec g.inPragma
else:
gcomma(g, n, emptyContext)
of nkImportStmt, nkExportStmt: of nkImportStmt, nkExportStmt:
if n.kind == nkImportStmt: if n.kind == nkImportStmt:
putWithSpace(g, tkImport, "import") putWithSpace(g, tkImport, "import")

View file

@ -370,7 +370,7 @@ proc trackPragmaStmt(tracked: PEffects, n: PNode) =
# list the computed effects up to here: # list the computed effects up to here:
listEffects(tracked) listEffects(tracked)
proc effectSpec(n: PNode, effectType = wRaises): PNode = proc effectSpec(n: PNode, effectType: TSpecialWord): PNode =
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
var it = n.sons[i] var it = n.sons[i]
if it.kind == nkExprColonExpr and whichPragma(it) == effectType: if it.kind == nkExprColonExpr and whichPragma(it) == effectType:
@ -380,8 +380,7 @@ proc effectSpec(n: PNode, effectType = wRaises): PNode =
result.add(it.sons[1]) result.add(it.sons[1])
return return
proc documentEffect(n, x: PNode, effectType: TSpecialWord, idx: int) = proc documentEffect(n, x: PNode, effectType: TSpecialWord, idx: int): PNode =
var x = x
let spec = effectSpec(x, effectType) let spec = effectSpec(x, effectType)
if isNil(spec): if isNil(spec):
let s = n.sons[namePos].sym let s = n.sons[namePos].sym
@ -399,18 +398,20 @@ proc documentEffect(n, x: PNode, effectType: TSpecialWord, idx: int) =
# set the type so that the following analysis doesn't screw up: # set the type so that the following analysis doesn't screw up:
effects.sons[i].typ = real[i].typ effects.sons[i].typ = real[i].typ
var pair = newNode(nkExprColonExpr, n.info, @[ result = newNode(nkExprColonExpr, n.info, @[
newIdentNode(getIdent(specialWords[effectType]), n.info), effects]) newIdentNode(getIdent(specialWords[effectType]), n.info), effects])
if x.kind == nkEmpty:
x = newNodeI(nkPragma, n.info)
n.sons[pragmasPos] = x
x.add(pair)
proc documentRaises*(n: PNode) = proc documentRaises*(n: PNode) =
if n.sons[namePos].kind != nkSym: return if n.sons[namePos].kind != nkSym: return
documentEffect(n, n.sons[pragmasPos], wRaises, exceptionEffects) let pragmas = n.sons[pragmasPos]
documentEffect(n, n.sons[pragmasPos], wTags, tagEffects) let p1 = documentEffect(n, pragmas, wRaises, exceptionEffects)
let p2 = documentEffect(n, pragmas, wTags, tagEffects)
if p1 != nil or p2 != nil:
if pragmas.kind == nkEmpty:
n.sons[pragmasPos] = newNodeI(nkPragma, n.info)
if p1 != nil: n.sons[pragmasPos].add p1
if p2 != nil: n.sons[pragmasPos].add p2
template notGcSafe(t): expr = {tfGcSafe, tfNoSideEffect} * t.flags == {} template notGcSafe(t): expr = {tfGcSafe, tfNoSideEffect} * t.flags == {}
@ -621,7 +622,8 @@ proc track(tracked: PEffects, n: PNode) =
useVar(tracked, n) useVar(tracked, n)
of nkRaiseStmt: of nkRaiseStmt:
n.sons[0].info = n.info n.sons[0].info = n.info
throws(tracked.exc, n.sons[0]) #throws(tracked.exc, n.sons[0])
addEffect(tracked, n.sons[0], useLineInfo=false)
for i in 0 .. <safeLen(n): for i in 0 .. <safeLen(n):
track(tracked, n.sons[i]) track(tracked, n.sons[i])
of nkCallKinds: of nkCallKinds:

View file

@ -1,3 +1,12 @@
#
#
# The Nim Compiler
# (c) Copyright 2014 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
import renderer, strutils, ast, msgs, types, astalgo import renderer, strutils, ast, msgs, types, astalgo
const defaultParamSeparator* = "," const defaultParamSeparator* = ","
@ -26,7 +35,7 @@ proc renderPlainSymbolName*(n: PNode): string =
result = renderPlainSymbolName(n[<n.len]) result = renderPlainSymbolName(n[<n.len])
else: else:
internalError(n.info, "renderPlainSymbolName() with " & $n.kind) internalError(n.info, "renderPlainSymbolName() with " & $n.kind)
assert (not result.isNil) assert(not result.isNil)
proc renderType(n: PNode): string = proc renderType(n: PNode): string =
## Returns a string with the node type or the empty string. ## Returns a string with the node type or the empty string.

View file

@ -0,0 +1 @@
--threads:on

View file

@ -217,7 +217,7 @@ proc raiseOSError*(msg: string = "") {.noinline, rtl, extern: "nos$1",
## ``GetLastError`` is checked before ``errno``. ## ``GetLastError`` is checked before ``errno``.
## If no error flag is set, the message ``unknown OS error`` is used. ## If no error flag is set, the message ``unknown OS error`` is used.
## ##
## **Deprecated since version 0.9.4**: use the other ``OSError`` proc. ## **Deprecated since version 0.9.4**: use the other ``raiseOSError`` proc.
if len(msg) == 0: if len(msg) == 0:
var m = osErrorMsg() var m = osErrorMsg()
raise newException(OSError, if m.len > 0: m else: "unknown OS error") raise newException(OSError, if m.len > 0: m else: "unknown OS error")
@ -234,7 +234,7 @@ proc `$`*(err: OSErrorCode): string {.borrow.}
proc osErrorMsg*(errorCode: OSErrorCode): string = proc osErrorMsg*(errorCode: OSErrorCode): string =
## Converts an OS error code into a human readable string. ## Converts an OS error code into a human readable string.
## ##
## The error code can be retrieved using the ``OSLastError`` proc. ## The error code can be retrieved using the ``osLastError`` proc.
## ##
## If conversion fails, or ``errorCode`` is ``0`` then ``""`` will be ## If conversion fails, or ``errorCode`` is ``0`` then ``""`` will be
## returned. ## returned.
@ -265,7 +265,7 @@ proc raiseOSError*(errorCode: OSErrorCode) =
## Raises an ``OSError`` exception. The ``errorCode`` will determine the ## Raises an ``OSError`` exception. The ``errorCode`` will determine the
## message, ``osErrorMsg`` will be used to get this message. ## message, ``osErrorMsg`` will be used to get this message.
## ##
## The error code can be retrieved using the ``OSLastError`` proc. ## The error code can be retrieved using the ``osLastError`` proc.
## ##
## If the error code is ``0`` or an error message could not be retrieved, ## If the error code is ``0`` or an error message could not be retrieved,
## the message ``unknown OS error`` will be used. ## the message ``unknown OS error`` will be used.
@ -884,7 +884,7 @@ proc sameFileContent*(path1, path2: string): bool {.rtl, extern: "nos$1",
close(b) close(b)
type type
TFilePermission* = enum ## file access permission; modelled after UNIX FilePermission* = enum ## file access permission; modelled after UNIX
fpUserExec, ## execute access for the file owner fpUserExec, ## execute access for the file owner
fpUserWrite, ## write access for the file owner fpUserWrite, ## write access for the file owner
fpUserRead, ## read access for the file owner fpUserRead, ## read access for the file owner
@ -895,7 +895,9 @@ type
fpOthersWrite, ## write access for others fpOthersWrite, ## write access for others
fpOthersRead ## read access for others fpOthersRead ## read access for others
proc getFilePermissions*(filename: string): set[TFilePermission] {. {.deprecated: [TFilePermission: FilePermission].}
proc getFilePermissions*(filename: string): set[FilePermission] {.
rtl, extern: "nos$1", tags: [ReadDirEffect].} = rtl, extern: "nos$1", tags: [ReadDirEffect].} =
## retrieves file permissions for `filename`. `OSError` is raised in case of ## retrieves file permissions for `filename`. `OSError` is raised in case of
## an error. On Windows, only the ``readonly`` flag is checked, every other ## an error. On Windows, only the ``readonly`` flag is checked, every other
@ -927,7 +929,7 @@ proc getFilePermissions*(filename: string): set[TFilePermission] {.
else: else:
result = {fpUserExec..fpOthersRead} result = {fpUserExec..fpOthersRead}
proc setFilePermissions*(filename: string, permissions: set[TFilePermission]) {. proc setFilePermissions*(filename: string, permissions: set[FilePermission]) {.
rtl, extern: "nos$1", tags: [WriteDirEffect].} = rtl, extern: "nos$1", tags: [WriteDirEffect].} =
## sets the file permissions for `filename`. `OSError` is raised in case of ## sets the file permissions for `filename`. `OSError` is raised in case of
## an error. On Windows, only the ``readonly`` flag is changed, depending on ## an error. On Windows, only the ``readonly`` flag is changed, depending on
@ -1231,13 +1233,15 @@ iterator walkFiles*(pattern: string): string {.tags: [ReadDirEffect].} =
globfree(addr(f)) globfree(addr(f))
type type
TPathComponent* = enum ## Enumeration specifying a path component. PathComponent* = enum ## Enumeration specifying a path component.
pcFile, ## path refers to a file pcFile, ## path refers to a file
pcLinkToFile, ## path refers to a symbolic link to a file pcLinkToFile, ## path refers to a symbolic link to a file
pcDir, ## path refers to a directory pcDir, ## path refers to a directory
pcLinkToDir ## path refers to a symbolic link to a directory pcLinkToDir ## path refers to a symbolic link to a directory
iterator walkDir*(dir: string): tuple[kind: TPathComponent, path: string] {. {.deprecated: [TPathComponent: PathComponent].}
iterator walkDir*(dir: string): tuple[kind: PathComponent, path: string] {.
tags: [ReadDirEffect].} = tags: [ReadDirEffect].} =
## walks over the directory `dir` and yields for each directory or file in ## walks over the directory `dir` and yields for each directory or file in
## `dir`. The component type and full path for each item is returned. ## `dir`. The component type and full path for each item is returned.
@ -1580,7 +1584,7 @@ proc copyDirWithPermissions*(source, dest: string,
else: discard else: discard
proc inclFilePermissions*(filename: string, proc inclFilePermissions*(filename: string,
permissions: set[TFilePermission]) {. permissions: set[FilePermission]) {.
rtl, extern: "nos$1", tags: [ReadDirEffect, WriteDirEffect].} = rtl, extern: "nos$1", tags: [ReadDirEffect, WriteDirEffect].} =
## a convenience procedure for: ## a convenience procedure for:
## ##
@ -1589,7 +1593,7 @@ proc inclFilePermissions*(filename: string,
setFilePermissions(filename, getFilePermissions(filename)+permissions) setFilePermissions(filename, getFilePermissions(filename)+permissions)
proc exclFilePermissions*(filename: string, proc exclFilePermissions*(filename: string,
permissions: set[TFilePermission]) {. permissions: set[FilePermission]) {.
rtl, extern: "nos$1", tags: [ReadDirEffect, WriteDirEffect].} = rtl, extern: "nos$1", tags: [ReadDirEffect, WriteDirEffect].} =
## a convenience procedure for: ## a convenience procedure for:
## ##
@ -1885,9 +1889,9 @@ type
FileInfo* = object FileInfo* = object
## Contains information associated with a file object. ## Contains information associated with a file object.
id*: tuple[device: DeviceId, file: FileId] # Device and file id. id*: tuple[device: DeviceId, file: FileId] # Device and file id.
kind*: TPathComponent # Kind of file object - directory, symlink, etc. kind*: PathComponent # Kind of file object - directory, symlink, etc.
size*: BiggestInt # Size of file. size*: BiggestInt # Size of file.
permissions*: set[TFilePermission] # File permissions permissions*: set[FilePermission] # File permissions
linkCount*: BiggestInt # Number of hard links the file object has. linkCount*: BiggestInt # Number of hard links the file object has.
lastAccessTime*: Time # Time file was last accessed. lastAccessTime*: Time # Time file was last accessed.
lastWriteTime*: Time # Time file was last modified/written to. lastWriteTime*: Time # Time file was last modified/written to.

View file

@ -46,7 +46,6 @@ Bugs
- VM: ptr/ref T cannot work in general - VM: ptr/ref T cannot work in general
- scopes are still broken for generic instantiation! - scopes are still broken for generic instantiation!
- compilation of niminst takes way too long. looks like a regression - compilation of niminst takes way too long. looks like a regression
- docgen: sometimes effects are listed twice
- blocks can "export" an identifier but the CCG generates {} for them ... - blocks can "export" an identifier but the CCG generates {} for them ...