add custom pragma support for var and let symbols (#9582)
* add custom pragma support for var and let symbols * updated changelog for custom pragmas on var and let symbols * add oldast switch for backwards compatibility
This commit is contained in:
parent
139fa396e8
commit
044cef152f
9 changed files with 77 additions and 20 deletions
|
|
@ -1087,6 +1087,13 @@ proc newSym*(symKind: TSymKind, name: PIdent, owner: PSym,
|
|||
when debugIds:
|
||||
registerId(result)
|
||||
|
||||
proc astdef*(s: PSym): PNode =
|
||||
# get only the definition (initializer) portion of the ast
|
||||
if s.ast != nil and s.ast.kind == nkIdentDefs:
|
||||
s.ast[2]
|
||||
else:
|
||||
s.ast
|
||||
|
||||
proc isMetaType*(t: PType): bool =
|
||||
return t.kind in tyMetaTypes or
|
||||
(t.kind == tyStatic and t.n == nil) or
|
||||
|
|
|
|||
|
|
@ -291,6 +291,7 @@ proc testCompileOption*(conf: ConfigRef; switch: string, info: TLineInfo): bool
|
|||
of "patterns": result = contains(conf.options, optPatterns)
|
||||
of "excessivestacktrace": result = contains(conf.globalOptions, optExcessiveStackTrace)
|
||||
of "nilseqs": result = contains(conf.options, optNilSeqs)
|
||||
of "oldast": result = contains(conf.options, optOldAst)
|
||||
else: invalidCmdLineOption(conf, passCmd1, switch, info)
|
||||
|
||||
proc processPath(conf: ConfigRef; path: string, info: TLineInfo,
|
||||
|
|
@ -508,6 +509,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
|||
localError(conf, info, errOnOrOffExpectedButXFound % arg)
|
||||
of "laxstrings": processOnOffSwitch(conf, {optLaxStrings}, arg, pass, info)
|
||||
of "nilseqs": processOnOffSwitch(conf, {optNilSeqs}, arg, pass, info)
|
||||
of "oldast": processOnOffSwitch(conf, {optOldAst}, arg, pass, info)
|
||||
of "checks", "x": processOnOffSwitch(conf, ChecksOptions, arg, pass, info)
|
||||
of "floatchecks":
|
||||
processOnOffSwitch(conf, {optNaNCheck, optInfCheck}, arg, pass, info)
|
||||
|
|
|
|||
|
|
@ -257,9 +257,9 @@ proc canon*(n: PNode; o: Operators): PNode =
|
|||
for i in 0 ..< n.len:
|
||||
result.sons[i] = canon(n.sons[i], o)
|
||||
elif n.kind == nkSym and n.sym.kind == skLet and
|
||||
n.sym.ast.getMagic in (someEq + someAdd + someMul + someMin +
|
||||
n.sym.astdef.getMagic in (someEq + someAdd + someMul + someMin +
|
||||
someMax + someHigh + {mUnaryLt} + someSub + someLen + someDiv):
|
||||
result = n.sym.ast.copyTree
|
||||
result = n.sym.astdef.copyTree
|
||||
else:
|
||||
result = n
|
||||
case result.getMagic
|
||||
|
|
@ -395,8 +395,8 @@ proc usefulFact(n: PNode; o: Operators): PNode =
|
|||
# if a:
|
||||
# ...
|
||||
# We make can easily replace 'a' by '2 < x' here:
|
||||
if n.sym.ast != nil:
|
||||
result = usefulFact(n.sym.ast, o)
|
||||
if n.sym.astdef != nil:
|
||||
result = usefulFact(n.sym.astdef, o)
|
||||
elif n.kind == nkStmtListExpr:
|
||||
result = usefulFact(n.lastSon, o)
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@ type # please make sure we have under 32 options
|
|||
optMemTracker,
|
||||
optHotCodeReloading,
|
||||
optLaxStrings,
|
||||
optNilSeqs
|
||||
optNilSeqs,
|
||||
optOldAst
|
||||
|
||||
TOptions* = set[TOption]
|
||||
TGlobalOption* = enum # **keep binary compatible**
|
||||
|
|
|
|||
|
|
@ -330,9 +330,9 @@ proc semIdentDef(c: PContext, n: PNode, kind: TSymKind): PSym =
|
|||
proc checkNilable(c: PContext; v: PSym) =
|
||||
if {sfGlobal, sfImportC} * v.flags == {sfGlobal} and
|
||||
{tfNotNil, tfNeedsInit} * v.typ.flags != {}:
|
||||
if v.ast.isNil:
|
||||
if v.astdef.isNil:
|
||||
message(c.config, v.info, warnProveInit, v.name.s)
|
||||
elif tfNotNil in v.typ.flags and tfNotNil notin v.ast.typ.flags:
|
||||
elif tfNotNil in v.typ.flags and tfNotNil notin v.astdef.typ.flags:
|
||||
message(c.config, v.info, warnProveInit, v.name.s)
|
||||
|
||||
include semasgn
|
||||
|
|
@ -518,8 +518,6 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
|||
message(c.config, a.info, warnShadowIdent, v.name.s)
|
||||
if a.kind != nkVarTuple:
|
||||
if def.kind != nkEmpty:
|
||||
# this is needed for the evaluation pass and for the guard checking:
|
||||
v.ast = def
|
||||
if sfThread in v.flags: localError(c.config, def.info, errThreadvarCannotInit)
|
||||
setVarType(c, v, typ)
|
||||
b = newNodeI(nkIdentDefs, a.info)
|
||||
|
|
@ -531,6 +529,23 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
|||
addSon(b, a.sons[length-2])
|
||||
addSon(b, copyTree(def))
|
||||
addToVarSection(c, result, n, b)
|
||||
if optOldAst in c.config.options:
|
||||
if def.kind != nkEmpty:
|
||||
v.ast = def
|
||||
else:
|
||||
# this is needed for the evaluation pass, guard checking
|
||||
# and custom pragmas:
|
||||
var ast = newNodeI(nkIdentDefs, a.info)
|
||||
if a[j].kind == nkPragmaExpr:
|
||||
var p = newNodeI(nkPragmaExpr, a.info)
|
||||
p.add newSymNode(v)
|
||||
p.add a[j][1].copyTree
|
||||
ast.add p
|
||||
else:
|
||||
ast.add newSymNode(v)
|
||||
ast.add a.sons[length-2].copyTree
|
||||
ast.add def
|
||||
v.ast = ast
|
||||
else:
|
||||
if def.kind in {nkPar, nkTupleConstr}: v.ast = def[j]
|
||||
# bug #7663, for 'nim check' this can be a non-tuple:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue