idetools improvements
This commit is contained in:
parent
12bc0419da
commit
79aaf213d6
10 changed files with 53 additions and 35 deletions
|
|
@ -311,6 +311,7 @@ type
|
||||||
const
|
const
|
||||||
tyPureObject* = tyTuple
|
tyPureObject* = tyTuple
|
||||||
GcTypeKinds* = {tyRef, tySequence, tyString}
|
GcTypeKinds* = {tyRef, tySequence, tyString}
|
||||||
|
tyError* = tyProxy # as an errornous node should match everything
|
||||||
|
|
||||||
type
|
type
|
||||||
TTypeKinds* = set[TTypeKind]
|
TTypeKinds* = set[TTypeKind]
|
||||||
|
|
|
||||||
|
|
@ -433,7 +433,9 @@ proc debugTree(n: PNode, indent: int, maxRecDepth: int): PRope =
|
||||||
appf(result, ",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)])
|
appf(result, ",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)])
|
||||||
of nkSym:
|
of nkSym:
|
||||||
appf(result, ",$N$1\"sym\": $2_$3",
|
appf(result, ",$N$1\"sym\": $2_$3",
|
||||||
[istr, toRope(n.sym.name.s), toRope(n.sym.id)])
|
[istr, symToYaml(n.sym, indent, maxRecDepth),
|
||||||
|
toRope(n.sym.id)])
|
||||||
|
#[istr, toRope(n.sym.name.s), toRope(n.sym.id)])
|
||||||
of nkIdent:
|
of nkIdent:
|
||||||
if n.ident != nil:
|
if n.ident != nil:
|
||||||
appf(result, ",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)])
|
appf(result, ",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)])
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,14 @@ proc considerAcc*(n: PNode): PIdent =
|
||||||
|
|
||||||
proc errorSym*(n: PNode): PSym =
|
proc errorSym*(n: PNode): PSym =
|
||||||
## creates an error symbol to avoid cascading errors (for IDE support)
|
## creates an error symbol to avoid cascading errors (for IDE support)
|
||||||
result = newSym(skUnknown, considerAcc(n), getCurrOwner())
|
var m = n
|
||||||
|
# ensure that 'considerAcc' can't fail:
|
||||||
|
if m.kind == nkDotExpr: m = m.sons[1]
|
||||||
|
let ident = if m.kind in {nkIdent, nkSym, nkAccQuoted}:
|
||||||
|
considerAcc(m)
|
||||||
|
else:
|
||||||
|
getIdent("err:" & renderTree(m))
|
||||||
|
result = newSym(skUnknown, ident, getCurrOwner())
|
||||||
result.info = n.info
|
result.info = n.info
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -661,7 +661,7 @@ proc GlobalError*(info: TLineInfo, msg: TMsgKind, arg = "") =
|
||||||
liMessage(info, msg, arg, doRaise)
|
liMessage(info, msg, arg, doRaise)
|
||||||
|
|
||||||
proc LocalError*(info: TLineInfo, msg: TMsgKind, arg = "") =
|
proc LocalError*(info: TLineInfo, msg: TMsgKind, arg = "") =
|
||||||
if gCmd == cmdIdeTools and gErrorCounter > 10: return
|
#if gCmd == cmdIdeTools and gErrorCounter > 10: return
|
||||||
liMessage(info, msg, arg, doNothing)
|
liMessage(info, msg, arg, doNothing)
|
||||||
|
|
||||||
proc Message*(info: TLineInfo, msg: TMsgKind, arg = "") =
|
proc Message*(info: TLineInfo, msg: TMsgKind, arg = "") =
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
|
||||||
#writeMatches(alt)
|
#writeMatches(alt)
|
||||||
if c.inCompilesContext > 0:
|
if c.inCompilesContext > 0:
|
||||||
# quick error message for performance of 'compiles' built-in:
|
# quick error message for performance of 'compiles' built-in:
|
||||||
LocalError(n.Info, errAmbiguousCallXYZ, "")
|
GlobalError(n.Info, errAmbiguousCallXYZ, "")
|
||||||
else:
|
else:
|
||||||
var args = "("
|
var args = "("
|
||||||
for i in countup(1, sonsLen(n) - 1):
|
for i in countup(1, sonsLen(n) - 1):
|
||||||
|
|
|
||||||
|
|
@ -228,7 +228,7 @@ proc newTypeS(kind: TTypeKind, c: PContext): PType =
|
||||||
|
|
||||||
proc errorType*(c: PContext): PType =
|
proc errorType*(c: PContext): PType =
|
||||||
## creates a type representing an error state
|
## creates a type representing an error state
|
||||||
result = newTypeS(tyEmpty, c)
|
result = newTypeS(tyError, c)
|
||||||
|
|
||||||
proc fillTypeS(dest: PType, kind: TTypeKind, c: PContext) =
|
proc fillTypeS(dest: PType, kind: TTypeKind, c: PContext) =
|
||||||
dest.kind = kind
|
dest.kind = kind
|
||||||
|
|
|
||||||
|
|
@ -995,6 +995,7 @@ proc propertyWriteAccess(c: PContext, n, nOrig, a: PNode): PNode =
|
||||||
analyseIfAddressTakenInCall(c, result)
|
analyseIfAddressTakenInCall(c, result)
|
||||||
else:
|
else:
|
||||||
LocalError(n.Info, errUndeclaredFieldX, id.s)
|
LocalError(n.Info, errUndeclaredFieldX, id.s)
|
||||||
|
result = emptyNode
|
||||||
|
|
||||||
proc takeImplicitAddr(c: PContext, n: PNode): PNode =
|
proc takeImplicitAddr(c: PContext, n: PNode): PNode =
|
||||||
case n.kind
|
case n.kind
|
||||||
|
|
|
||||||
|
|
@ -159,10 +159,10 @@ proc semRange(c: PContext, n: PNode, prev: PType): PType =
|
||||||
if isRange(n[1]): result = semRangeAux(c, n[1], prev)
|
if isRange(n[1]): result = semRangeAux(c, n[1], prev)
|
||||||
else:
|
else:
|
||||||
LocalError(n.sons[0].info, errRangeExpected)
|
LocalError(n.sons[0].info, errRangeExpected)
|
||||||
result = errorType(c)
|
result = newOrPrevType(tyError, prev, c)
|
||||||
else:
|
else:
|
||||||
LocalError(n.info, errXExpectsOneTypeParam, "range")
|
LocalError(n.info, errXExpectsOneTypeParam, "range")
|
||||||
result = errorType(c)
|
result = newOrPrevType(tyError, prev, c)
|
||||||
|
|
||||||
proc semArray(c: PContext, n: PNode, prev: PType): PType =
|
proc semArray(c: PContext, n: PNode, prev: PType): PType =
|
||||||
var indx, base: PType
|
var indx, base: PType
|
||||||
|
|
@ -182,7 +182,7 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType =
|
||||||
addSonSkipIntLit(result, base)
|
addSonSkipIntLit(result, base)
|
||||||
else:
|
else:
|
||||||
LocalError(n.info, errArrayExpectsTwoTypeParams)
|
LocalError(n.info, errArrayExpectsTwoTypeParams)
|
||||||
result = errorType(c)
|
result = newOrPrevType(tyError, prev, c)
|
||||||
|
|
||||||
proc semOrdinal(c: PContext, n: PNode, prev: PType): PType =
|
proc semOrdinal(c: PContext, n: PNode, prev: PType): PType =
|
||||||
result = newOrPrevType(tyOrdinal, prev, c)
|
result = newOrPrevType(tyOrdinal, prev, c)
|
||||||
|
|
@ -194,7 +194,7 @@ proc semOrdinal(c: PContext, n: PNode, prev: PType): PType =
|
||||||
addSonSkipIntLit(result, base)
|
addSonSkipIntLit(result, base)
|
||||||
else:
|
else:
|
||||||
LocalError(n.info, errXExpectsOneTypeParam, "ordinal")
|
LocalError(n.info, errXExpectsOneTypeParam, "ordinal")
|
||||||
result = errorType(c)
|
result = newOrPrevType(tyError, prev, c)
|
||||||
|
|
||||||
proc semTypeIdent(c: PContext, n: PNode): PSym =
|
proc semTypeIdent(c: PContext, n: PNode): PSym =
|
||||||
if n.kind == nkSym:
|
if n.kind == nkSym:
|
||||||
|
|
@ -518,7 +518,9 @@ proc semObjectNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
if concreteBase.kind == tyObject and tfFinal notin concreteBase.flags:
|
if concreteBase.kind == tyObject and tfFinal notin concreteBase.flags:
|
||||||
addInheritedFields(c, check, pos, concreteBase)
|
addInheritedFields(c, check, pos, concreteBase)
|
||||||
else:
|
else:
|
||||||
localError(n.sons[1].info, errInheritanceOnlyWithNonFinalObjects)
|
if concreteBase.kind != tyError:
|
||||||
|
localError(n.sons[1].info, errInheritanceOnlyWithNonFinalObjects)
|
||||||
|
base = nil
|
||||||
if n.kind != nkObjectTy: InternalError(n.info, "semObjectNode")
|
if n.kind != nkObjectTy: InternalError(n.info, "semObjectNode")
|
||||||
result = newOrPrevType(tyObject, prev, c)
|
result = newOrPrevType(tyObject, prev, c)
|
||||||
rawAddSon(result, base)
|
rawAddSon(result, base)
|
||||||
|
|
@ -730,15 +732,15 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
|
||||||
var isConcrete = true
|
var isConcrete = true
|
||||||
if s.typ == nil:
|
if s.typ == nil:
|
||||||
LocalError(n.info, errCannotInstantiateX, s.name.s)
|
LocalError(n.info, errCannotInstantiateX, s.name.s)
|
||||||
return errorType(c)
|
return newOrPrevType(tyError, prev, c)
|
||||||
elif s.typ.kind != tyGenericBody:
|
elif s.typ.kind != tyGenericBody:
|
||||||
isConcrete = false
|
isConcrete = false
|
||||||
elif s.typ.containerID == 0:
|
elif s.typ.containerID == 0:
|
||||||
InternalError(n.info, "semtypes.semGeneric")
|
InternalError(n.info, "semtypes.semGeneric")
|
||||||
return errorType(c)
|
return newOrPrevType(tyError, prev, c)
|
||||||
elif sonsLen(n) != sonsLen(s.typ):
|
elif sonsLen(n) != sonsLen(s.typ):
|
||||||
LocalError(n.info, errWrongNumberOfArguments)
|
LocalError(n.info, errWrongNumberOfArguments)
|
||||||
return errorType(c)
|
return newOrPrevType(tyError, prev, c)
|
||||||
addSonSkipIntLit(result, s.typ)
|
addSonSkipIntLit(result, s.typ)
|
||||||
# iterate over arguments:
|
# iterate over arguments:
|
||||||
for i in countup(1, sonsLen(n)-1):
|
for i in countup(1, sonsLen(n)-1):
|
||||||
|
|
@ -750,7 +752,7 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
|
||||||
if isConcrete:
|
if isConcrete:
|
||||||
if s.ast == nil:
|
if s.ast == nil:
|
||||||
LocalError(n.info, errCannotInstantiateX, s.name.s)
|
LocalError(n.info, errCannotInstantiateX, s.name.s)
|
||||||
result = errorType(c)
|
result = newOrPrevType(tyError, prev, c)
|
||||||
else:
|
else:
|
||||||
result = instGenericContainer(c, n, result)
|
result = instGenericContainer(c, n, result)
|
||||||
|
|
||||||
|
|
@ -781,7 +783,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
if sonsLen(n) == 1: result = semTypeNode(c, n.sons[0], prev)
|
if sonsLen(n) == 1: result = semTypeNode(c, n.sons[0], prev)
|
||||||
else:
|
else:
|
||||||
LocalError(n.info, errTypeExpected)
|
LocalError(n.info, errTypeExpected)
|
||||||
result = errorType(c)
|
result = newOrPrevType(tyError, prev, c)
|
||||||
of nkCallKinds:
|
of nkCallKinds:
|
||||||
let op = n.sons[0].ident
|
let op = n.sons[0].ident
|
||||||
if op.id in {ord(wAnd), ord(wOr)} or op.s == "|":
|
if op.id in {ord(wAnd), ord(wOr)} or op.s == "|":
|
||||||
|
|
@ -790,10 +792,10 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
t2 = semTypeNode(c, n.sons[2], nil)
|
t2 = semTypeNode(c, n.sons[2], nil)
|
||||||
if t1 == nil:
|
if t1 == nil:
|
||||||
LocalError(n.sons[1].info, errTypeExpected)
|
LocalError(n.sons[1].info, errTypeExpected)
|
||||||
result = errorType(c)
|
result = newOrPrevType(tyError, prev, c)
|
||||||
elif t2 == nil:
|
elif t2 == nil:
|
||||||
LocalError(n.sons[2].info, errTypeExpected)
|
LocalError(n.sons[2].info, errTypeExpected)
|
||||||
result = errorType(c)
|
result = newOrPrevType(tyError, prev, c)
|
||||||
else:
|
else:
|
||||||
result = newTypeS(tyTypeClass, c)
|
result = newTypeS(tyTypeClass, c)
|
||||||
result.addSonSkipIntLit(t1)
|
result.addSonSkipIntLit(t1)
|
||||||
|
|
@ -826,7 +828,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
var s = semTypeIdent(c, n)
|
var s = semTypeIdent(c, n)
|
||||||
if s.typ == nil:
|
if s.typ == nil:
|
||||||
LocalError(n.info, errTypeExpected)
|
LocalError(n.info, errTypeExpected)
|
||||||
result = errorType(c)
|
result = newOrPrevType(tyError, prev, c)
|
||||||
elif prev == nil:
|
elif prev == nil:
|
||||||
result = s.typ
|
result = s.typ
|
||||||
else:
|
else:
|
||||||
|
|
@ -844,7 +846,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
markUsed(n, n.sym)
|
markUsed(n, n.sym)
|
||||||
else:
|
else:
|
||||||
LocalError(n.info, errTypeExpected)
|
LocalError(n.info, errTypeExpected)
|
||||||
result = errorType(c)
|
result = newOrPrevType(tyError, prev, c)
|
||||||
of nkObjectTy: result = semObjectNode(c, n, prev)
|
of nkObjectTy: result = semObjectNode(c, n, prev)
|
||||||
of nkTupleTy: result = semTuple(c, n, prev)
|
of nkTupleTy: result = semTuple(c, n, prev)
|
||||||
of nkRefTy: result = semAnyRef(c, n, tyRef, prev)
|
of nkRefTy: result = semAnyRef(c, n, tyRef, prev)
|
||||||
|
|
@ -872,11 +874,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
of nkBlockType: result = semBlockType(c, n, prev)
|
of nkBlockType: result = semBlockType(c, n, prev)
|
||||||
else:
|
else:
|
||||||
LocalError(n.info, errTypeExpected)
|
LocalError(n.info, errTypeExpected)
|
||||||
if prev != nil and prev.kind == tyForward:
|
result = newOrPrevType(tyError, prev, c)
|
||||||
prev.kind = tyProxy
|
|
||||||
result = prev
|
|
||||||
else:
|
|
||||||
result = errorType(c)
|
|
||||||
|
|
||||||
proc setMagicType(m: PSym, kind: TTypeKind, size: int) =
|
proc setMagicType(m: PSym, kind: TTypeKind, size: int) =
|
||||||
m.typ.kind = kind
|
m.typ.kind = kind
|
||||||
|
|
|
||||||
|
|
@ -160,8 +160,9 @@ proc concreteType(c: TCandidate, t: PType): PType =
|
||||||
# proc sort[T](cmp: proc(a, b: T): int = cmp)
|
# proc sort[T](cmp: proc(a, b: T): int = cmp)
|
||||||
if result.kind != tyGenericParam: break
|
if result.kind != tyGenericParam: break
|
||||||
of tyGenericInvokation:
|
of tyGenericInvokation:
|
||||||
assert false
|
InternalError("cannot resolve type: " & typeToString(t))
|
||||||
else:
|
result = t
|
||||||
|
else:
|
||||||
result = t # Note: empty is valid here
|
result = t # Note: empty is valid here
|
||||||
|
|
||||||
proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
|
proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
|
||||||
|
|
@ -538,7 +539,7 @@ proc typeRel(c: var TCandidate, f, a: PType): TTypeRelation =
|
||||||
if result == isGeneric: put(c.bindings, f, a)
|
if result == isGeneric: put(c.bindings, f, a)
|
||||||
else:
|
else:
|
||||||
result = isNone
|
result = isNone
|
||||||
of tyExpr, tyStmt:
|
of tyExpr, tyStmt, tyProxy:
|
||||||
result = isGeneric
|
result = isGeneric
|
||||||
else: internalError("typeRel: " & $f.kind)
|
else: internalError("typeRel: " & $f.kind)
|
||||||
|
|
||||||
|
|
@ -648,6 +649,10 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType,
|
||||||
if skipTypes(f, abstractVar).kind in {tyTuple}:
|
if skipTypes(f, abstractVar).kind in {tyTuple}:
|
||||||
result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c)
|
result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c)
|
||||||
of isNone:
|
of isNone:
|
||||||
|
# we test for this here to not slow down ``typeRel``:
|
||||||
|
if a.kind == tyProxy:
|
||||||
|
inc(m.genericMatches)
|
||||||
|
return copyTree(arg)
|
||||||
result = userConvMatch(c, m, f, a, arg)
|
result = userConvMatch(c, m, f, a, arg)
|
||||||
# check for a base type match, which supports openarray[T] without []
|
# check for a base type match, which supports openarray[T] without []
|
||||||
# constructor in a call:
|
# constructor in a call:
|
||||||
|
|
|
||||||
|
|
@ -402,7 +402,7 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||||
"float", "float32", "float64", "float128",
|
"float", "float32", "float64", "float128",
|
||||||
"uint", "uint8", "uint16", "uint32", "uint64",
|
"uint", "uint8", "uint16", "uint32", "uint64",
|
||||||
"bignum", "const ",
|
"bignum", "const ",
|
||||||
"!", "varargs[$1]", "iter[$1]", "proxy[$1]", "TypeClass" ]
|
"!", "varargs[$1]", "iter[$1]", "Error Type", "TypeClass" ]
|
||||||
var t = typ
|
var t = typ
|
||||||
result = ""
|
result = ""
|
||||||
if t == nil: return
|
if t == nil: return
|
||||||
|
|
@ -485,7 +485,7 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||||
addSep(prag)
|
addSep(prag)
|
||||||
add(prag, "thread")
|
add(prag, "thread")
|
||||||
if len(prag) != 0: add(result, "{." & prag & ".}")
|
if len(prag) != 0: add(result, "{." & prag & ".}")
|
||||||
of tyVarargs, tyIter, tyProxy:
|
of tyVarargs, tyIter:
|
||||||
result = typeToStr[t.kind] % typeToString(t.sons[0])
|
result = typeToStr[t.kind] % typeToString(t.sons[0])
|
||||||
else:
|
else:
|
||||||
result = typeToStr[t.kind]
|
result = typeToStr[t.kind]
|
||||||
|
|
@ -929,16 +929,20 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool =
|
||||||
result = typeAllowedAux(marker, t.sons[0], skVar)
|
result = typeAllowedAux(marker, t.sons[0], skVar)
|
||||||
of tyPtr:
|
of tyPtr:
|
||||||
result = typeAllowedAux(marker, t.sons[0], skVar)
|
result = typeAllowedAux(marker, t.sons[0], skVar)
|
||||||
of tyArrayConstr, tyTuple, tySet, tyConst, tyMutable, tyIter, tyProxy:
|
of tyArrayConstr, tyTuple, tySet, tyConst, tyMutable, tyIter:
|
||||||
for i in countup(0, sonsLen(t) - 1):
|
for i in countup(0, sonsLen(t) - 1):
|
||||||
result = typeAllowedAux(marker, t.sons[i], kind)
|
result = typeAllowedAux(marker, t.sons[i], kind)
|
||||||
if not result: break
|
if not result: break
|
||||||
of tyObject:
|
of tyObject:
|
||||||
if kind == skConst: return false
|
if kind == skConst: return false
|
||||||
for i in countup(0, sonsLen(t) - 1):
|
for i in countup(0, sonsLen(t) - 1):
|
||||||
result = typeAllowedAux(marker, t.sons[i], kind)
|
result = typeAllowedAux(marker, t.sons[i], kind)
|
||||||
if not result: break
|
if not result: break
|
||||||
if result and t.n != nil: result = typeAllowedNode(marker, t.n, kind)
|
if result and t.n != nil: result = typeAllowedNode(marker, t.n, kind)
|
||||||
|
of tyProxy:
|
||||||
|
# for now same as error node; we say it's a valid type as it should
|
||||||
|
# prevent cascading errors:
|
||||||
|
result = true
|
||||||
|
|
||||||
proc typeAllowed(t: PType, kind: TSymKind): bool =
|
proc typeAllowed(t: PType, kind: TSymKind): bool =
|
||||||
var marker = InitIntSet()
|
var marker = InitIntSet()
|
||||||
|
|
@ -1076,10 +1080,10 @@ proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt =
|
||||||
if result < 0: return
|
if result < 0: return
|
||||||
if a < maxAlign: a = maxAlign
|
if a < maxAlign: a = maxAlign
|
||||||
result = align(result, a)
|
result = align(result, a)
|
||||||
of tyGenericInst, tyDistinct, tyGenericBody, tyMutable, tyConst, tyIter,
|
of tyGenericInst, tyDistinct, tyGenericBody, tyMutable, tyConst, tyIter:
|
||||||
tyProxy:
|
|
||||||
result = computeSizeAux(lastSon(typ), a)
|
result = computeSizeAux(lastSon(typ), a)
|
||||||
else:
|
of tyProxy: result = 1
|
||||||
|
else:
|
||||||
#internalError("computeSizeAux()")
|
#internalError("computeSizeAux()")
|
||||||
result = - 1
|
result = - 1
|
||||||
typ.size = result
|
typ.size = result
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue