mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-29 01:14:41 +00:00
.pure enums are much more convenient to use now
This commit is contained in:
@@ -60,6 +60,11 @@ proc checkModuleName*(n: PNode; doLocalError=true): int32 =
|
||||
else:
|
||||
result = fullPath.fileInfoIdx
|
||||
|
||||
proc importPureEnumField*(c: PContext; s: PSym) =
|
||||
var check = strTableGet(c.importTable.symbols, s.name)
|
||||
if check == nil:
|
||||
strTableAdd(c.pureEnumFields, s)
|
||||
|
||||
proc rawImportSymbol(c: PContext, s: PSym) =
|
||||
# This does not handle stubs, because otherwise loading on demand would be
|
||||
# pointless in practice. So importing stubs is fine here!
|
||||
@@ -75,7 +80,7 @@ proc rawImportSymbol(c: PContext, s: PSym) =
|
||||
strTableAdd(c.importTable.symbols, s)
|
||||
if s.kind == skType:
|
||||
var etyp = s.typ
|
||||
if etyp.kind in {tyBool, tyEnum} and sfPure notin s.flags:
|
||||
if etyp.kind in {tyBool, tyEnum}:
|
||||
for j in countup(0, sonsLen(etyp.n) - 1):
|
||||
var e = etyp.n.sons[j].sym
|
||||
if e.kind != skEnumField:
|
||||
@@ -91,7 +96,10 @@ proc rawImportSymbol(c: PContext, s: PSym) =
|
||||
break
|
||||
check = nextIdentIter(it, c.importTable.symbols)
|
||||
if e != nil:
|
||||
rawImportSymbol(c, e)
|
||||
if sfPure notin s.flags:
|
||||
rawImportSymbol(c, e)
|
||||
else:
|
||||
importPureEnumField(c, e)
|
||||
else:
|
||||
# rodgen assures that converters and patterns are no stubs
|
||||
if s.kind == skConverter: addConverter(c, s)
|
||||
|
||||
@@ -286,7 +286,7 @@ proc lookUp*(c: PContext, n: PNode): PSym =
|
||||
|
||||
type
|
||||
TLookupFlag* = enum
|
||||
checkAmbiguity, checkUndeclared, checkModule
|
||||
checkAmbiguity, checkUndeclared, checkModule, checkPureEnumFields
|
||||
|
||||
proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym =
|
||||
const allExceptModule = {low(TSymKind)..high(TSymKind)}-{skModule,skPackage}
|
||||
@@ -297,6 +297,8 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym =
|
||||
result = searchInScopes(c, ident).skipAlias(n)
|
||||
else:
|
||||
result = searchInScopes(c, ident, allExceptModule).skipAlias(n)
|
||||
if result == nil and checkPureEnumFields in flags:
|
||||
result = strTableGet(c.pureEnumFields, ident)
|
||||
if result == nil and checkUndeclared in flags:
|
||||
fixSpelling(n, ident, searchInScopes)
|
||||
errorUndeclaredIdentifier(c, n.info, ident.s)
|
||||
|
||||
@@ -65,7 +65,7 @@ type
|
||||
efWantStmt, efAllowStmt, efDetermineType, efExplain,
|
||||
efAllowDestructor, efWantValue, efOperand, efNoSemCheck,
|
||||
efNoProcvarCheck, efNoEvaluateGeneric, efInCall, efFromHlo,
|
||||
|
||||
|
||||
TExprFlags* = set[TExprFlag]
|
||||
|
||||
TTypeAttachedOp* = enum
|
||||
@@ -112,6 +112,7 @@ type
|
||||
semGenerateInstance*: proc (c: PContext, fn: PSym, pt: TIdTable,
|
||||
info: TLineInfo): PSym
|
||||
includedFiles*: IntSet # used to detect recursive include files
|
||||
pureEnumFields*: TStrTable # pure enum fields that can be used unambiguously
|
||||
userPragmas*: TStrTable
|
||||
evalContext*: PEvalContext
|
||||
unknownIdents*: IntSet # ids of all unknown identifiers to prevent
|
||||
@@ -210,6 +211,7 @@ proc newContext*(graph: ModuleGraph; module: PSym; cache: IdentCache): PContext
|
||||
result.converters = @[]
|
||||
result.patterns = @[]
|
||||
result.includedFiles = initIntSet()
|
||||
initStrTable(result.pureEnumFields)
|
||||
initStrTable(result.userPragmas)
|
||||
result.generics = @[]
|
||||
result.unknownIdents = initIntSet()
|
||||
|
||||
@@ -2115,8 +2115,10 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
if nfSem in n.flags: return
|
||||
case n.kind
|
||||
of nkIdent, nkAccQuoted:
|
||||
let checks = if efNoEvaluateGeneric in flags: {checkUndeclared}
|
||||
else: {checkUndeclared, checkModule, checkAmbiguity}
|
||||
let checks = if efNoEvaluateGeneric in flags:
|
||||
{checkUndeclared, checkPureEnumFields}
|
||||
else:
|
||||
{checkUndeclared, checkModule, checkAmbiguity, checkPureEnumFields}
|
||||
var s = qualifiedLookUp(c, n, checks)
|
||||
if c.matchedConcept == nil: semCaptureSym(s, c.p.owner)
|
||||
result = semSym(c, n, s, flags)
|
||||
|
||||
@@ -105,6 +105,10 @@ proc lookup(c: PContext, n: PNode, flags: TSemGenericFlags,
|
||||
result = n
|
||||
let ident = considerQuotedIdent(n)
|
||||
var s = searchInScopes(c, ident).skipAlias(n)
|
||||
if s == nil:
|
||||
s = strTableGet(c.pureEnumFields, ident)
|
||||
if s != nil and contains(c.ambiguousSymbols, s.id):
|
||||
s = nil
|
||||
if s == nil:
|
||||
if ident.id notin ctx.toMixin and withinMixin notin flags:
|
||||
errorUndeclaredIdentifier(c, n.info, ident.s)
|
||||
|
||||
@@ -88,7 +88,9 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
|
||||
if not isPure: strTableAdd(c.module.tab, e)
|
||||
addSon(result.n, newSymNode(e))
|
||||
styleCheckDef(e)
|
||||
if sfGenSym notin e.flags and not isPure: addDecl(c, e)
|
||||
if sfGenSym notin e.flags:
|
||||
if not isPure: addDecl(c, e)
|
||||
else: importPureEnumField(c, e)
|
||||
if isPure and strTableIncl(symbols, e):
|
||||
wrongRedefinition(e.info, e.name.s)
|
||||
inc(counter)
|
||||
|
||||
Reference in New Issue
Block a user