bugfix: generic instantiation across module boundaries

This commit is contained in:
Araq 2011-06-06 08:45:11 +02:00
commit 42eb21be7b
11 changed files with 414 additions and 237 deletions

View file

@ -264,7 +264,7 @@ proc renderIndexTerm(d: PDoc, n: PRstNode): PRope =
proc genComment(d: PDoc, n: PNode): PRope =
var dummyHasToc: bool
if (n.comment != nil) and startsWith(n.comment, "##"):
if n.comment != nil and startsWith(n.comment, "##"):
result = renderRstToOut(d, rstParse(n.comment, true, toFilename(n.info),
toLineNumber(n.info), toColumn(n.info),
dummyHasToc))
@ -385,8 +385,9 @@ proc renderHeadline(d: PDoc, n: PRstNode): PRope =
d.tocPart[length].refname = refname
d.tocPart[length].n = n
d.tocPart[length].header = result
result = dispF("<h$1><a class=\"toc-backref\" id=\"$2\" href=\"#$2_toc\">$3</a></h$1>",
"\\rsth$4{$3}\\label{$2}$n", [toRope(n.level),
result = dispF(
"<h$1><a class=\"toc-backref\" id=\"$2\" href=\"#$2_toc\">$3</a></h$1>",
"\\rsth$4{$3}\\label{$2}$n", [toRope(n.level),
d.tocPart[length].refname, result,
toRope(chr(n.level - 1 + ord('A')) & "")])
else:
@ -405,7 +406,7 @@ proc renderOverline(d: PDoc, n: PRstNode): PRope =
else:
result = dispF("<h$1 id=\"$2\"><center>$3</center></h$1>",
"\\rstov$4{$3}\\label{$2}$n", [toRope(n.level),
toRope(rstnodeToRefname(n)), t, toRope(chr(n.level - 1 + ord('A')) & "")])
toRope(rstnodeToRefname(n)), t, toRope($chr(n.level - 1 + ord('A')))])
proc renderRstToRst(d: PDoc, n: PRstNode): PRope
proc renderRstSons(d: PDoc, n: PRstNode): PRope =

View file

@ -25,13 +25,13 @@ type
TSrcGen*{.final.} = object
indent*: int
lineLen*: int
pos*: int # current position for iteration over the buffer
idx*: int # current token index for iteration over the buffer
pos*: int # current position for iteration over the buffer
idx*: int # current token index for iteration over the buffer
tokens*: TRenderTokSeq
buf*: string
pendingNL*: int # negative if not active; else contains the
# indentation value
comStack*: seq[PNode] # comment stack
pendingNL*: int # negative if not active; else contains the
# indentation value
comStack*: seq[PNode] # comment stack
flags*: TRenderFlags
@ -123,13 +123,13 @@ proc toNimChar(c: Char): string =
proc makeNimString(s: string): string =
result = "\""
for i in countup(0, len(s) + 0 - 1): add(result, toNimChar(s[i]))
for i in countup(0, len(s)-1): add(result, toNimChar(s[i]))
add(result, '\"')
proc putComment(g: var TSrcGen, s: string) =
var i = 0
var comIndent = 1
var isCode = (len(s) >= 2) and (s[0 + 1] != ' ')
var isCode = (len(s) >= 2) and (s[1] != ' ')
var ind = g.lineLen
var com = ""
while true:
@ -166,9 +166,8 @@ proc putComment(g: var TSrcGen, s: string) =
while s[j] > ' ': inc(j)
if not isCode and (g.lineLen + (j - i) > MaxLineLen):
put(g, tkComment, com)
com = ""
optNL(g, ind)
com = com & '#' & repeatChar(comIndent)
com = '#' & repeatChar(comIndent)
while s[i] > ' ':
add(com, s[i])
inc(i)
@ -198,7 +197,7 @@ proc maxLineLength(s: string): int =
proc putRawStr(g: var TSrcGen, kind: TTokType, s: string) =
var i = 0
var hi = len(s) + 0 - 1
var hi = len(s) - 1
var str = ""
while i <= hi:
case s[i]
@ -219,7 +218,7 @@ proc putRawStr(g: var TSrcGen, kind: TTokType, s: string) =
put(g, kind, str)
proc containsNL(s: string): bool =
for i in countup(0, len(s) + 0 - 1):
for i in countup(0, len(s) - 1):
case s[i]
of '\x0D', '\x0A':
return true
@ -513,8 +512,7 @@ proc gstmts(g: var TSrcGen, n: PNode, c: TContext) =
if rfLongMode in c.flags: dedent(g)
proc gif(g: var TSrcGen, n: PNode) =
var
c: TContext
var c: TContext
gsub(g, n.sons[0].sons[0])
initContext(c)
putWithSpace(g, tkColon, ":")
@ -826,7 +824,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
of nkAccQuoted:
put(g, tkAccent, "`")
if n.len > 0: gsub(g, n.sons[0])
for i in 0 .. <n.len:
for i in 1 .. <n.len:
put(g, tkSpaces, Space)
gsub(g, n.sons[i])
put(g, tkAccent, "`")

View file

@ -34,10 +34,11 @@ proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
else:
GlobalError(n.info, errExprXHasNoType,
renderTree(result, {renderNoComments}))
proc semSymGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
result = symChoice(c, n, s)
proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
if s.kind == skType and efAllowType notin flags:
GlobalError(n.info, errATypeHasNoValue)
case s.kind
of skProc, skMethod, skIterator, skConverter:
if not (sfProcVar in s.flags) and (s.typ.callConv == ccDefault) and
@ -56,25 +57,29 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
# It is clear that ``[]`` means two totally different things. Thus, we
# copy `x`'s AST into each context, so that the type fixup phase can
# deal with two different ``[]``.
#
#
markUsed(n, s)
if s.typ.kind in ConstAbstractTypes:
if s.typ.kind in ConstAbstractTypes:
result = copyTree(s.ast)
result.typ = s.typ
result.info = n.info
else:
else:
result = newSymNode(s, n.info)
of skMacro: result = semMacroExpr(c, n, s)
of skTemplate: result = semTemplateExpr(c, n, s)
of skVar:
of skVar:
markUsed(n, s)
# if a proc accesses a global variable, it is not side effect free:
if sfGlobal in s.flags: incl(c.p.owner.flags, sfSideEffect)
result = newSymNode(s, n.info)
of skGenericParam:
of skGenericParam:
if s.ast == nil: InternalError(n.info, "no default for")
result = semExpr(c, s.ast)
else:
of skType:
if efAllowType notin flags: GlobalError(n.info, errATypeHasNoValue)
markUsed(n, s)
result = newSymNode(s, n.info)
else:
markUsed(n, s)
result = newSymNode(s, n.info)
@ -1037,7 +1042,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
var s = qualifiedLookup(c, n.sons[0], {checkUndeclared})
if s != nil and s.kind in {skProc, skMethod, skConverter, skIterator}:
# type parameters: partial generic specialization
n.sons[0] = semSym(c, n.sons[0], s, flags)
n.sons[0] = semSymGenericInstantiation(c, n.sons[0], s)
result = explicitGenericInstantiation(c, n, s)
else:
result = semArrayAccess(c, n, flags)