nimsuggest improvements
This commit is contained in:
parent
a9706dcfa2
commit
fe30ec83e2
18 changed files with 112 additions and 54 deletions
|
|
@ -932,6 +932,7 @@ proc genAsmOrEmitStmt(p: BProc, t: PNode, isAsmStmt=false): PRope =
|
||||||
var j = 0
|
var j = 0
|
||||||
while x[j] in {' ', '\t'}: inc(j)
|
while x[j] in {' ', '\t'}: inc(j)
|
||||||
if x[j] in {'"', ':'}:
|
if x[j] in {'"', ':'}:
|
||||||
|
# don't modify the line if already in quotes or
|
||||||
# some clobber register list:
|
# some clobber register list:
|
||||||
app(result, x); app(result, tnl)
|
app(result, x); app(result, tnl)
|
||||||
elif x[j] != '\0':
|
elif x[j] != '\0':
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym): PNode =
|
||||||
evalTemplateAux(body, args, ctx, result)
|
evalTemplateAux(body, args, ctx, result)
|
||||||
if result.len == 1: result = result.sons[0]
|
if result.len == 1: result = result.sons[0]
|
||||||
else:
|
else:
|
||||||
globalError(result.info, errIllFormedAstX,
|
localError(result.info, errIllFormedAstX,
|
||||||
renderTree(result, {renderNoComments}))
|
renderTree(result, {renderNoComments}))
|
||||||
else:
|
else:
|
||||||
result = copyNode(body)
|
result = copyNode(body)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# The Nim Compiler
|
# The Nim Compiler
|
||||||
# (c) Copyright 2012 Andreas Rumpf
|
# (c) Copyright 2015 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -22,7 +22,9 @@ proc considerQuotedIdent*(n: PNode): PIdent =
|
||||||
of nkSym: result = n.sym.name
|
of nkSym: result = n.sym.name
|
||||||
of nkAccQuoted:
|
of nkAccQuoted:
|
||||||
case n.len
|
case n.len
|
||||||
of 0: globalError(n.info, errIdentifierExpected, renderTree(n))
|
of 0:
|
||||||
|
localError(n.info, errIdentifierExpected, renderTree(n))
|
||||||
|
result = getIdent"<Error>"
|
||||||
of 1: result = considerQuotedIdent(n.sons[0])
|
of 1: result = considerQuotedIdent(n.sons[0])
|
||||||
else:
|
else:
|
||||||
var id = ""
|
var id = ""
|
||||||
|
|
@ -31,12 +33,15 @@ proc considerQuotedIdent*(n: PNode): PIdent =
|
||||||
case x.kind
|
case x.kind
|
||||||
of nkIdent: id.add(x.ident.s)
|
of nkIdent: id.add(x.ident.s)
|
||||||
of nkSym: id.add(x.sym.name.s)
|
of nkSym: id.add(x.sym.name.s)
|
||||||
else: globalError(n.info, errIdentifierExpected, renderTree(n))
|
else:
|
||||||
|
localError(n.info, errIdentifierExpected, renderTree(n))
|
||||||
|
return getIdent"<Error>"
|
||||||
result = getIdent(id)
|
result = getIdent(id)
|
||||||
of nkOpenSymChoice, nkClosedSymChoice: result = n.sons[0].sym.name
|
of nkOpenSymChoice, nkClosedSymChoice: result = n.sons[0].sym.name
|
||||||
else:
|
else:
|
||||||
globalError(n.info, errIdentifierExpected, renderTree(n))
|
localError(n.info, errIdentifierExpected, renderTree(n))
|
||||||
|
result = getIdent"<Error>"
|
||||||
|
|
||||||
template addSym*(scope: PScope, s: PSym) =
|
template addSym*(scope: PScope, s: PSym) =
|
||||||
strTableAdd(scope.symbols, s)
|
strTableAdd(scope.symbols, s)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ path:"$lib/packages/docutils"
|
||||||
path:"$nim/compiler"
|
path:"$nim/compiler"
|
||||||
|
|
||||||
define:useStdoutAsStdmsg
|
define:useStdoutAsStdmsg
|
||||||
symbol:nimsuggest
|
|
||||||
define:nimsuggest
|
define:nimsuggest
|
||||||
|
|
||||||
cs:partial
|
cs:partial
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ type
|
||||||
const
|
const
|
||||||
MaxStackSize* = 64 ## max required stack size by the VM
|
MaxStackSize* = 64 ## max required stack size by the VM
|
||||||
|
|
||||||
proc patternError(n: PNode) =
|
proc patternError(n: PNode) =
|
||||||
localError(n.info, errIllFormedAstX, renderTree(n, {renderNoComments}))
|
localError(n.info, errIllFormedAstX, renderTree(n, {renderNoComments}))
|
||||||
|
|
||||||
proc add(code: var TPatternCode, op: TOpcode) {.inline.} =
|
proc add(code: var TPatternCode, op: TOpcode) {.inline.} =
|
||||||
|
|
|
||||||
|
|
@ -324,7 +324,10 @@ proc parseSymbol(p: var TParser, allowNil = false): PNode =
|
||||||
getTok(p)
|
getTok(p)
|
||||||
else:
|
else:
|
||||||
parMessage(p, errIdentifierExpected, p.tok)
|
parMessage(p, errIdentifierExpected, p.tok)
|
||||||
getTok(p) # BUGFIX: We must consume a token here to prevent endless loops!
|
# BUGFIX: We must consume a token here to prevent endless loops!
|
||||||
|
# But: this really sucks for idetools and keywords, so we don't do it
|
||||||
|
# if it is a keyword:
|
||||||
|
if not isKeyword(p.tok.tokType): getTok(p)
|
||||||
result = ast.emptyNode
|
result = ast.emptyNode
|
||||||
|
|
||||||
proc indexExpr(p: var TParser): PNode =
|
proc indexExpr(p: var TParser): PNode =
|
||||||
|
|
|
||||||
|
|
@ -447,7 +447,9 @@ proc semAsmOrEmit*(con: PContext, n: PNode, marker: char): PNode =
|
||||||
addSon(result, newStrNode(nkStrLit, $marker))
|
addSon(result, newStrNode(nkStrLit, $marker))
|
||||||
if c < 0: break
|
if c < 0: break
|
||||||
a = c + 1
|
a = c + 1
|
||||||
else: illFormedAst(n)
|
else:
|
||||||
|
illFormedAstLocal(n)
|
||||||
|
result = newNode(nkAsmStmt, n.info)
|
||||||
|
|
||||||
proc pragmaEmit(c: PContext, n: PNode) =
|
proc pragmaEmit(c: PContext, n: PNode) =
|
||||||
discard getStrLitNode(c, n)
|
discard getStrLitNode(c, n)
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,24 @@ proc finishMethod(c: PContext, s: PSym)
|
||||||
|
|
||||||
proc indexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode
|
proc indexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode
|
||||||
|
|
||||||
|
template semIdeForTemplateOrGenericCheck(n, requiresCheck) =
|
||||||
|
# we check quickly if the node is where the cursor is
|
||||||
|
when defined(nimsuggest):
|
||||||
|
if n.info.fileIndex == gTrackPos.fileIndex and n.info.line == gTrackPos.line:
|
||||||
|
requiresCheck = true
|
||||||
|
|
||||||
|
template semIdeForTemplateOrGeneric(c: PContext; n: PNode;
|
||||||
|
requiresCheck: bool) =
|
||||||
|
# use only for idetools support; this is pretty slow so generics and
|
||||||
|
# templates perform some quick check whether the cursor is actually in
|
||||||
|
# the generic or template.
|
||||||
|
when defined(nimsuggest):
|
||||||
|
assert gCmd == cmdIdeTools
|
||||||
|
if requiresCheck:
|
||||||
|
if optIdeDebug in gGlobalOptions:
|
||||||
|
echo "passing to safeSemExpr: ", renderTree(n)
|
||||||
|
discard safeSemExpr(c, n)
|
||||||
|
|
||||||
proc typeMismatch(n: PNode, formal, actual: PType) =
|
proc typeMismatch(n: PNode, formal, actual: PType) =
|
||||||
if formal.kind != tyError and actual.kind != tyError:
|
if formal.kind != tyError and actual.kind != tyError:
|
||||||
localError(n.info, errGenerated, msgKindToString(errTypeMismatch) &
|
localError(n.info, errGenerated, msgKindToString(errTypeMismatch) &
|
||||||
|
|
@ -359,13 +377,7 @@ proc semConstBoolExpr(c: PContext, n: PNode): PNode =
|
||||||
localError(n.info, errConstExprExpected)
|
localError(n.info, errConstExprExpected)
|
||||||
result = nn
|
result = nn
|
||||||
|
|
||||||
type
|
proc semGenericStmt(c: PContext, n: PNode): PNode
|
||||||
TSemGenericFlag = enum
|
|
||||||
withinBind, withinTypeDesc, withinMixin
|
|
||||||
TSemGenericFlags = set[TSemGenericFlag]
|
|
||||||
|
|
||||||
proc semGenericStmt(c: PContext, n: PNode, flags: TSemGenericFlags,
|
|
||||||
ctx: var IntSet): PNode
|
|
||||||
|
|
||||||
include semtypes, semtempl, semgnrc, semstmts, semexprs
|
include semtypes, semtempl, semgnrc, semstmts, semexprs
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ proc liftBodyObj(c: TLiftCtx; typ, x, y: PNode) =
|
||||||
of nkRecList:
|
of nkRecList:
|
||||||
for t in items(typ): liftBodyObj(c, t, x, y)
|
for t in items(typ): liftBodyObj(c, t, x, y)
|
||||||
else:
|
else:
|
||||||
illFormedAst(typ)
|
illFormedAstLocal(typ)
|
||||||
|
|
||||||
proc newAsgnCall(op: PSym; x, y: PNode): PNode =
|
proc newAsgnCall(op: PSym; x, y: PNode): PNode =
|
||||||
result = newNodeI(nkCall, x.info)
|
result = newNodeI(nkCall, x.info)
|
||||||
|
|
|
||||||
|
|
@ -307,6 +307,9 @@ proc markIndirect*(c: PContext, s: PSym) {.inline.} =
|
||||||
proc illFormedAst*(n: PNode) =
|
proc illFormedAst*(n: PNode) =
|
||||||
globalError(n.info, errIllFormedAstX, renderTree(n, {renderNoComments}))
|
globalError(n.info, errIllFormedAstX, renderTree(n, {renderNoComments}))
|
||||||
|
|
||||||
|
proc illFormedAstLocal*(n: PNode) =
|
||||||
|
localError(n.info, errIllFormedAstX, renderTree(n, {renderNoComments}))
|
||||||
|
|
||||||
proc checkSonsLen*(n: PNode, length: int) =
|
proc checkSonsLen*(n: PNode, length: int) =
|
||||||
if sonsLen(n) != length: illFormedAst(n)
|
if sonsLen(n) != length: illFormedAst(n)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ proc semForObjectFields(c: TFieldsCtx, typ, forLoop, father: PNode) =
|
||||||
of nkRecList:
|
of nkRecList:
|
||||||
for t in items(typ): semForObjectFields(c, t, forLoop, father)
|
for t in items(typ): semForObjectFields(c, t, forLoop, father)
|
||||||
else:
|
else:
|
||||||
illFormedAst(typ)
|
illFormedAstLocal(typ)
|
||||||
|
|
||||||
proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
|
proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
|
||||||
# so that 'break' etc. work as expected, we produce
|
# so that 'break' etc. work as expected, we produce
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,23 @@ proc getIdentNode(n: PNode): PNode =
|
||||||
else:
|
else:
|
||||||
illFormedAst(n)
|
illFormedAst(n)
|
||||||
result = n
|
result = n
|
||||||
|
|
||||||
|
type
|
||||||
|
GenericCtx = object
|
||||||
|
toMixin: IntSet
|
||||||
|
cursorInBody: bool # only for nimsuggest
|
||||||
|
|
||||||
|
type
|
||||||
|
TSemGenericFlag = enum
|
||||||
|
withinBind, withinTypeDesc, withinMixin
|
||||||
|
TSemGenericFlags = set[TSemGenericFlag]
|
||||||
|
|
||||||
|
proc semGenericStmt(c: PContext, n: PNode,
|
||||||
|
flags: TSemGenericFlags, ctx: var GenericCtx): PNode
|
||||||
|
|
||||||
proc semGenericStmtScope(c: PContext, n: PNode,
|
proc semGenericStmtScope(c: PContext, n: PNode,
|
||||||
flags: TSemGenericFlags,
|
flags: TSemGenericFlags,
|
||||||
ctx: var IntSet): PNode =
|
ctx: var GenericCtx): PNode =
|
||||||
openScope(c)
|
openScope(c)
|
||||||
result = semGenericStmt(c, n, flags, ctx)
|
result = semGenericStmt(c, n, flags, ctx)
|
||||||
closeScope(c)
|
closeScope(c)
|
||||||
|
|
@ -37,7 +50,8 @@ template macroToExpand(s: expr): expr =
|
||||||
s.kind in {skMacro, skTemplate} and (s.typ.len == 1 or sfImmediate in s.flags)
|
s.kind in {skMacro, skTemplate} and (s.typ.len == 1 or sfImmediate in s.flags)
|
||||||
|
|
||||||
proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym,
|
proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym,
|
||||||
ctx: var IntSet): PNode =
|
ctx: var GenericCtx): PNode =
|
||||||
|
semIdeForTemplateOrGenericCheck(n, ctx.cursorInBody)
|
||||||
incl(s.flags, sfUsed)
|
incl(s.flags, sfUsed)
|
||||||
case s.kind
|
case s.kind
|
||||||
of skUnknown:
|
of skUnknown:
|
||||||
|
|
@ -83,17 +97,17 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym,
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
|
|
||||||
proc lookup(c: PContext, n: PNode, flags: TSemGenericFlags,
|
proc lookup(c: PContext, n: PNode, flags: TSemGenericFlags,
|
||||||
ctx: var IntSet): PNode =
|
ctx: var GenericCtx): PNode =
|
||||||
result = n
|
result = n
|
||||||
let ident = considerQuotedIdent(n)
|
let ident = considerQuotedIdent(n)
|
||||||
var s = searchInScopes(c, ident).skipAlias(n)
|
var s = searchInScopes(c, ident).skipAlias(n)
|
||||||
if s == nil:
|
if s == nil:
|
||||||
if ident.id notin ctx and withinMixin notin flags:
|
if ident.id notin ctx.toMixin and withinMixin notin flags:
|
||||||
localError(n.info, errUndeclaredIdentifier, ident.s)
|
localError(n.info, errUndeclaredIdentifier, ident.s)
|
||||||
else:
|
else:
|
||||||
if withinBind in flags:
|
if withinBind in flags:
|
||||||
result = symChoice(c, n, s, scClosed)
|
result = symChoice(c, n, s, scClosed)
|
||||||
elif s.name.id in ctx:
|
elif s.name.id in ctx.toMixin:
|
||||||
result = symChoice(c, n, s, scForceOpen)
|
result = symChoice(c, n, s, scForceOpen)
|
||||||
else:
|
else:
|
||||||
result = semGenericStmtSymbol(c, n, s, ctx)
|
result = semGenericStmtSymbol(c, n, s, ctx)
|
||||||
|
|
@ -105,8 +119,10 @@ proc newDot(n, b: PNode): PNode =
|
||||||
result.add(b)
|
result.add(b)
|
||||||
|
|
||||||
proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags,
|
proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags,
|
||||||
ctx: var IntSet; isMacro: var bool): PNode =
|
ctx: var GenericCtx; isMacro: var bool): PNode =
|
||||||
assert n.kind == nkDotExpr
|
assert n.kind == nkDotExpr
|
||||||
|
semIdeForTemplateOrGenericCheck(n, ctx.cursorInBody)
|
||||||
|
|
||||||
let luf = if withinMixin notin flags: {checkUndeclared} else: {}
|
let luf = if withinMixin notin flags: {checkUndeclared} else: {}
|
||||||
|
|
||||||
var s = qualifiedLookUp(c, n, luf)
|
var s = qualifiedLookUp(c, n, luf)
|
||||||
|
|
@ -122,7 +138,7 @@ proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags,
|
||||||
isMacro = s.kind in {skTemplate, skMacro}
|
isMacro = s.kind in {skTemplate, skMacro}
|
||||||
if withinBind in flags:
|
if withinBind in flags:
|
||||||
result = newDot(result, symChoice(c, n, s, scClosed))
|
result = newDot(result, symChoice(c, n, s, scClosed))
|
||||||
elif s.name.id in ctx:
|
elif s.name.id in ctx.toMixin:
|
||||||
result = newDot(result, symChoice(c, n, s, scForceOpen))
|
result = newDot(result, symChoice(c, n, s, scForceOpen))
|
||||||
else:
|
else:
|
||||||
let sym = semGenericStmtSymbol(c, n, s, ctx)
|
let sym = semGenericStmtSymbol(c, n, s, ctx)
|
||||||
|
|
@ -137,9 +153,11 @@ proc addTempDecl(c: PContext; n: PNode; kind: TSymKind) =
|
||||||
styleCheckDef(n.info, s, kind)
|
styleCheckDef(n.info, s, kind)
|
||||||
|
|
||||||
proc semGenericStmt(c: PContext, n: PNode,
|
proc semGenericStmt(c: PContext, n: PNode,
|
||||||
flags: TSemGenericFlags, ctx: var IntSet): PNode =
|
flags: TSemGenericFlags, ctx: var GenericCtx): PNode =
|
||||||
result = n
|
result = n
|
||||||
if gCmd == cmdIdeTools: suggestStmt(c, n)
|
#if gCmd == cmdIdeTools: suggestStmt(c, n)
|
||||||
|
semIdeForTemplateOrGenericCheck(n, ctx.cursorInBody)
|
||||||
|
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkIdent, nkAccQuoted:
|
of nkIdent, nkAccQuoted:
|
||||||
result = lookup(c, n, flags, ctx)
|
result = lookup(c, n, flags, ctx)
|
||||||
|
|
@ -162,14 +180,15 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||||
of nkBind:
|
of nkBind:
|
||||||
result = semGenericStmt(c, n.sons[0], flags+{withinBind}, ctx)
|
result = semGenericStmt(c, n.sons[0], flags+{withinBind}, ctx)
|
||||||
of nkMixinStmt:
|
of nkMixinStmt:
|
||||||
result = semMixinStmt(c, n, ctx)
|
result = semMixinStmt(c, n, ctx.toMixin)
|
||||||
of nkCall, nkHiddenCallConv, nkInfix, nkPrefix, nkCommand, nkCallStrLit:
|
of nkCall, nkHiddenCallConv, nkInfix, nkPrefix, nkCommand, nkCallStrLit:
|
||||||
# check if it is an expression macro:
|
# check if it is an expression macro:
|
||||||
checkMinSonsLen(n, 1)
|
checkMinSonsLen(n, 1)
|
||||||
let fn = n.sons[0]
|
let fn = n.sons[0]
|
||||||
var s = qualifiedLookUp(c, fn, {})
|
var s = qualifiedLookUp(c, fn, {})
|
||||||
if s == nil and withinMixin notin flags and
|
if s == nil and withinMixin notin flags and
|
||||||
fn.kind in {nkIdent, nkAccQuoted} and considerQuotedIdent(fn).id notin ctx:
|
fn.kind in {nkIdent, nkAccQuoted} and
|
||||||
|
considerQuotedIdent(fn).id notin ctx.toMixin:
|
||||||
localError(n.info, errUndeclaredIdentifier, fn.renderTree)
|
localError(n.info, errUndeclaredIdentifier, fn.renderTree)
|
||||||
|
|
||||||
var first = 0
|
var first = 0
|
||||||
|
|
@ -177,7 +196,7 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||||
if s != nil:
|
if s != nil:
|
||||||
incl(s.flags, sfUsed)
|
incl(s.flags, sfUsed)
|
||||||
mixinContext = s.magic in {mDefined, mDefinedInScope, mCompiles}
|
mixinContext = s.magic in {mDefined, mDefinedInScope, mCompiles}
|
||||||
let scOption = if s.name.id in ctx: scForceOpen else: scOpen
|
let scOption = if s.name.id in ctx.toMixin: scForceOpen else: scOpen
|
||||||
case s.kind
|
case s.kind
|
||||||
of skMacro:
|
of skMacro:
|
||||||
if macroToExpand(s):
|
if macroToExpand(s):
|
||||||
|
|
@ -377,4 +396,9 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||||
else:
|
else:
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
result.sons[i] = semGenericStmt(c, n.sons[i], flags, ctx)
|
result.sons[i] = semGenericStmt(c, n.sons[i], flags, ctx)
|
||||||
|
|
||||||
|
proc semGenericStmt(c: PContext, n: PNode): PNode =
|
||||||
|
var ctx: GenericCtx
|
||||||
|
ctx.toMixin = initIntset()
|
||||||
|
result = semGenericStmt(c, n, {}, ctx)
|
||||||
|
semIdeForTemplateOrGeneric(c, result, ctx.cursorInBody)
|
||||||
|
|
|
||||||
|
|
@ -1060,8 +1060,9 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||||
else:
|
else:
|
||||||
if s.typ.sons[0] != nil and kind notin skIterators:
|
if s.typ.sons[0] != nil and kind notin skIterators:
|
||||||
addDecl(c, newSym(skUnknown, getIdent"result", nil, n.info))
|
addDecl(c, newSym(skUnknown, getIdent"result", nil, n.info))
|
||||||
var toBind = initIntSet()
|
openScope(c)
|
||||||
n.sons[bodyPos] = semGenericStmtScope(c, n.sons[bodyPos], {}, toBind)
|
n.sons[bodyPos] = semGenericStmt(c, n.sons[bodyPos])
|
||||||
|
closeScope(c)
|
||||||
fixupInstantiatedSymbols(c, s)
|
fixupInstantiatedSymbols(c, s)
|
||||||
if sfImportc in s.flags:
|
if sfImportc in s.flags:
|
||||||
# so we just ignore the body after semantic checking for importc:
|
# so we just ignore the body after semantic checking for importc:
|
||||||
|
|
|
||||||
|
|
@ -105,10 +105,11 @@ proc replaceIdentBySym(n: var PNode, s: PNode) =
|
||||||
else: illFormedAst(n)
|
else: illFormedAst(n)
|
||||||
|
|
||||||
type
|
type
|
||||||
TemplCtx {.pure, final.} = object
|
TemplCtx = object
|
||||||
c: PContext
|
c: PContext
|
||||||
toBind, toMixin, toInject: IntSet
|
toBind, toMixin, toInject: IntSet
|
||||||
owner: PSym
|
owner: PSym
|
||||||
|
cursorInBody: bool # only for nimsuggest
|
||||||
|
|
||||||
proc getIdentNode(c: var TemplCtx, n: PNode): PNode =
|
proc getIdentNode(c: var TemplCtx, n: PNode): PNode =
|
||||||
case n.kind
|
case n.kind
|
||||||
|
|
@ -259,8 +260,9 @@ proc semTemplSomeDecl(c: var TemplCtx, n: PNode, symKind: TSymKind; start=0) =
|
||||||
addLocalDecl(c, a.sons[j], symKind)
|
addLocalDecl(c, a.sons[j], symKind)
|
||||||
|
|
||||||
proc semPattern(c: PContext, n: PNode): PNode
|
proc semPattern(c: PContext, n: PNode): PNode
|
||||||
proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
|
proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
|
||||||
result = n
|
result = n
|
||||||
|
semIdeForTemplateOrGenericCheck(n, c.cursorInBody)
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkIdent:
|
of nkIdent:
|
||||||
if n.ident.id in c.toInject: return n
|
if n.ident.id in c.toInject: return n
|
||||||
|
|
@ -416,8 +418,9 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
result.sons[i] = semTemplBody(c, n.sons[i])
|
result.sons[i] = semTemplBody(c, n.sons[i])
|
||||||
|
|
||||||
proc semTemplBodyDirty(c: var TemplCtx, n: PNode): PNode =
|
proc semTemplBodyDirty(c: var TemplCtx, n: PNode): PNode =
|
||||||
result = n
|
result = n
|
||||||
|
semIdeForTemplateOrGenericCheck(n, c.cursorInBody)
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkIdent:
|
of nkIdent:
|
||||||
let s = qualifiedLookUp(c.c, n, {})
|
let s = qualifiedLookUp(c.c, n, {})
|
||||||
|
|
@ -524,6 +527,7 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
|
||||||
if s.typ.sons[0].kind notin {tyStmt, tyTypeDesc}:
|
if s.typ.sons[0].kind notin {tyStmt, tyTypeDesc}:
|
||||||
n.sons[bodyPos] = transformToExpr(n.sons[bodyPos])
|
n.sons[bodyPos] = transformToExpr(n.sons[bodyPos])
|
||||||
# only parameters are resolved, no type checking is performed
|
# only parameters are resolved, no type checking is performed
|
||||||
|
semIdeForTemplateOrGeneric(c, n.sons[bodyPos], ctx.cursorInBody)
|
||||||
closeScope(c)
|
closeScope(c)
|
||||||
popOwner()
|
popOwner()
|
||||||
s.ast = n
|
s.ast = n
|
||||||
|
|
|
||||||
|
|
@ -1178,8 +1178,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
return errorType(c)
|
return errorType(c)
|
||||||
result = typeExpr.typ.base
|
result = typeExpr.typ.base
|
||||||
if result.isMetaType:
|
if result.isMetaType:
|
||||||
var toBind = initIntSet()
|
var preprocessed = semGenericStmt(c, n)
|
||||||
var preprocessed = semGenericStmt(c, n, {}, toBind)
|
|
||||||
return makeTypeFromExpr(c, preprocessed)
|
return makeTypeFromExpr(c, preprocessed)
|
||||||
of nkIdent, nkAccQuoted:
|
of nkIdent, nkAccQuoted:
|
||||||
var s = semTypeIdent(c, n)
|
var s = semTypeIdent(c, n)
|
||||||
|
|
|
||||||
|
|
@ -256,19 +256,6 @@ proc findClosestSym(n: PNode): PNode =
|
||||||
result = findClosestSym(n.sons[i])
|
result = findClosestSym(n.sons[i])
|
||||||
if result != nil: return
|
if result != nil: return
|
||||||
|
|
||||||
proc safeSemExpr(c: PContext, n: PNode): PNode =
|
|
||||||
try:
|
|
||||||
result = c.semExpr(c, n)
|
|
||||||
except ERecoverableError:
|
|
||||||
result = ast.emptyNode
|
|
||||||
|
|
||||||
proc fuzzySemCheck(c: PContext, n: PNode): PNode =
|
|
||||||
result = safeSemExpr(c, n)
|
|
||||||
if result == nil or result.kind == nkEmpty:
|
|
||||||
result = newNodeI(n.kind, n.info)
|
|
||||||
if n.kind notin {nkNone..nkNilLit}:
|
|
||||||
for i in 0 .. < sonsLen(n): result.addSon(fuzzySemCheck(c, n.sons[i]))
|
|
||||||
|
|
||||||
var
|
var
|
||||||
usageSym*: PSym
|
usageSym*: PSym
|
||||||
lastLineInfo: TLineInfo
|
lastLineInfo: TLineInfo
|
||||||
|
|
@ -312,6 +299,21 @@ proc useSym*(sym: PSym): PNode =
|
||||||
result = newSymNode(sym)
|
result = newSymNode(sym)
|
||||||
markUsed(result.info, sym)
|
markUsed(result.info, sym)
|
||||||
|
|
||||||
|
proc safeSemExpr*(c: PContext, n: PNode): PNode =
|
||||||
|
# use only for idetools support!
|
||||||
|
try:
|
||||||
|
result = c.semExpr(c, n)
|
||||||
|
except ERecoverableError:
|
||||||
|
result = ast.emptyNode
|
||||||
|
|
||||||
|
proc fuzzySemCheck(c: PContext, n: PNode): PNode =
|
||||||
|
# use only for idetools support!
|
||||||
|
result = safeSemExpr(c, n)
|
||||||
|
if result == nil or result.kind == nkEmpty:
|
||||||
|
result = newNodeIT(n.kind, n.info, errorType(c))
|
||||||
|
if n.kind notin {nkNone..nkNilLit}:
|
||||||
|
for i in 0 .. < sonsLen(n): result.addSon(fuzzySemCheck(c, n.sons[i]))
|
||||||
|
|
||||||
proc suggestExpr*(c: PContext, node: PNode) =
|
proc suggestExpr*(c: PContext, node: PNode) =
|
||||||
if nfIsCursor notin node.flags:
|
if nfIsCursor notin node.flags:
|
||||||
if gTrackPos.line < 0: return
|
if gTrackPos.line < 0: return
|
||||||
|
|
@ -327,6 +329,8 @@ proc suggestExpr*(c: PContext, node: PNode) =
|
||||||
if n == nil: n = node
|
if n == nil: n = node
|
||||||
if n.kind == nkDotExpr:
|
if n.kind == nkDotExpr:
|
||||||
var obj = safeSemExpr(c, n.sons[0])
|
var obj = safeSemExpr(c, n.sons[0])
|
||||||
|
if optIdeDebug in gGlobalOptions:
|
||||||
|
echo "expression ", renderTree(obj), " has type ", typeToString(obj.typ)
|
||||||
suggestFieldAccess(c, obj, outputs)
|
suggestFieldAccess(c, obj, outputs)
|
||||||
else:
|
else:
|
||||||
suggestEverything(c, n, outputs)
|
suggestEverything(c, n, outputs)
|
||||||
|
|
|
||||||
|
|
@ -254,7 +254,7 @@ proc remove*[T](L: var DoublyLinkedList[T], n: DoublyLinkedNode[T]) =
|
||||||
proc prepend*[T](L: var SinglyLinkedRing[T], n: SinglyLinkedNode[T]) =
|
proc prepend*[T](L: var SinglyLinkedRing[T], n: SinglyLinkedNode[T]) =
|
||||||
## prepends a node `n` to `L`. Efficiency: O(1).
|
## prepends a node `n` to `L`. Efficiency: O(1).
|
||||||
if L.head != nil:
|
if L.head != nil:
|
||||||
n.next = L.head
|
n.next = L.head
|
||||||
L.head.next = n
|
L.head.next = n
|
||||||
else:
|
else:
|
||||||
n.next = n
|
n.next = n
|
||||||
|
|
|
||||||
1
todo.txt
1
todo.txt
|
|
@ -1,6 +1,7 @@
|
||||||
version 0.10
|
version 0.10
|
||||||
============
|
============
|
||||||
|
|
||||||
|
- nimsuggest: auto-completion needs to work in 'class' macros
|
||||||
- improve the docs for inheritance
|
- improve the docs for inheritance
|
||||||
- The bitwise 'not' operator will be renamed to 'bnot' to
|
- The bitwise 'not' operator will be renamed to 'bnot' to
|
||||||
prevent 'not 4 == 5' from compiling. -> requires 'mixin' annotation for procs!
|
prevent 'not 4 == 5' from compiling. -> requires 'mixin' annotation for procs!
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue