new type traits: GenericHead and StripGenericParams

This commit is contained in:
Zahary Karadjov 2016-08-25 02:14:25 +03:00
commit 52b241fd57
3 changed files with 62 additions and 5 deletions

View file

@ -86,9 +86,32 @@ proc semInstantiationInfo(c: PContext, n: PNode): PNode =
result.add(filename)
result.add(line)
proc toNode(t: PType, i: TLineInfo): PNode =
result = newNodeIT(nkType, i, t)
const
# these are types that use the bracket syntax for instantiation
# they can be subjected to the type traits `GenericHead` and
# `Uninstantiated`
tyUserDefinedGenerics* = {tyGenericInst, tyGenericInvocation,
tyUserTypeClassInst}
tyMagicGenerics* = {tySet, tySequence, tyArray, tyOpenArray}
tyGenericLike* = tyUserDefinedGenerics +
tyMagicGenerics +
{tyCompositeTypeClass}
proc uninstantiate(t: PType): PType =
result = case t.kind
of tyMagicGenerics: t
of tyUserDefinedGenerics: t.base
of tyCompositeTypeClass: uninstantiate t.sons[1]
else: t
proc evalTypeTrait(trait: PNode, operand: PType, context: PSym): PNode =
let typ = operand.skipTypes({tyTypeDesc})
case trait.sym.name.s.normalize
var typ = operand.skipTypes({tyTypeDesc})
case trait.sym.name.s
of "name":
result = newStrNode(nkStrLit, typ.typeToString(preferName))
result.typ = newType(tyString, context)
@ -97,6 +120,16 @@ proc evalTypeTrait(trait: PNode, operand: PType, context: PSym): PNode =
result = newIntNode(nkIntLit, typ.len - ord(typ.kind==tyProc))
result.typ = newType(tyInt, context)
result.info = trait.info
of "GenericHead":
var res = uninstantiate(typ)
if res == typ and res.kind notin tyMagicGenerics:
localError(trait.info,
"GenericHead expects a generic type. The given type was " &
typeToString(typ))
return newType(tyError, context).toNode(trait.info)
result = res.base.toNode(trait.info)
of "StripGenericParams":
result = uninstantiate(typ).toNode(trait.info)
else:
internalAssert false

View file

@ -1226,6 +1226,13 @@ proc fixupTypeOf(c: PContext, prev: PType, typExpr: PNode) =
result.sym = prev.sym
assignType(prev, result)
proc symFromExpectedTypeNode(c: PContext, n: PNode): PSym =
if n.kind == nkType:
result = symFromType(n.typ, n.info)
else:
localError(n.info, "xx")
result = errorSym(c, n)
proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
result = nil
when defined(nimsuggest):
@ -1316,7 +1323,9 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
result = semTypeNode(c, whenResult, prev)
of nkBracketExpr:
checkMinSonsLen(n, 2)
var s = semTypeIdent(c, n.sons[0])
var head = n.sons[0]
var s = if head.kind notin nkCallKinds: semTypeIdent(c, head)
else: symFromExpectedTypeNode(c, semExpr(c, head))
case s.magic
of mArray: result = semArray(c, n, prev)
of mOpenArray: result = semContainer(c, n, tyOpenArray, "openarray", prev)