Do not generate object fields for constants

This commit is contained in:
Emery Hemingway 2021-09-06 17:37:36 +02:00
parent b940a458a1
commit e556fa26e0
1 changed files with 34 additions and 30 deletions

View File

@ -78,10 +78,13 @@ proc toExport(n: sink PNode): PNode =
proc newEmpty(): PNode = newNode(nkEmpty) proc newEmpty(): PNode = newNode(nkEmpty)
proc isConst(sn: SchemaNode): bool = proc isConst(scm: Schema; sn: SchemaNode): bool =
case sn.kind case sn.kind
of snkLiteral: true of snkLiteral: result = true
else: false of snkRef:
if sn.refPath.len == 1:
result = isConst(scm, scm.definitions[sn.refPath[0]])
else: discard
proc isSymbolEnum(sn: SchemaNode): bool = proc isSymbolEnum(sn: SchemaNode): bool =
if sn.kind == snkOr: if sn.kind == snkOr:
@ -104,7 +107,7 @@ proc toEnumDef(name: string; sn: SchemaNode): PNode =
newEmpty(), newEmpty(),
sn.toEnumTy) sn.toEnumTy)
proc nimTypeOf(known: var TypeTable; sn: SchemaNode; name = ""): PNode = proc nimTypeOf(scm: Schema; known: var TypeTable; sn: SchemaNode; name = ""): PNode =
case sn.kind case sn.kind
of snkOr: of snkOr:
if sn.isSymbolEnum: if sn.isSymbolEnum:
@ -128,27 +131,28 @@ proc nimTypeOf(known: var TypeTable; sn: SchemaNode; name = ""): PNode =
case bn.altBranch.nodes.len case bn.altBranch.nodes.len
of 0, 1: discard of 0, 1: discard
of 2: of 2:
let label = bn.ident if not isConst(scm, bn.altBranch.nodes[1]):
recList.add nkIdentDefs.newNode.add( let label = bn.ident
label.accQuote.toExport, recList.add nkIdentDefs.newNode.add(
nimTypeOf(known, bn.altBranch.nodes[1], $label), label.accQuote.toExport,
newEmpty()) nimTypeOf(scm, known, bn.altBranch.nodes[1], $label),
newEmpty())
else: else:
for i, field in bn.altBranch.nodes: for i, field in bn.altBranch.nodes:
if i > 0: if i > 0 and (not isConst(scm, field)):
let label = field.ident let label = field.ident
recList.add nkIdentDefs.newNode.add( recList.add nkIdentDefs.newNode.add(
label.accQuote.toExport, label.accQuote.toExport,
nimTypeOf(known, field, $label), nimTypeOf(scm, known, field, $label),
newEmpty()) newEmpty())
else: else:
if bn.altBranch.isConst: if isConst(scm, bn.altBranch):
recList.add nkDiscardStmt.newNode.add(newEmpty()) recList.add nkDiscardStmt.newNode.add(newEmpty())
else: else:
let label = bn.ident let label = bn.ident
recList.add(nkIdentDefs.newNode.add( recList.add(nkIdentDefs.newNode.add(
label.accQuote, label.accQuote,
nimTypeOf(known, bn.altBranch, $label), nimTypeOf(scm, known, bn.altBranch, $label),
newEmpty())) newEmpty()))
let disc = nkDotExpr.newNode.add( let disc = nkDotExpr.newNode.add(
enumIdent, bn.altLabel.nimIdentNormalize.ident.accQuote) enumIdent, bn.altLabel.nimIdentNormalize.ident.accQuote)
@ -162,7 +166,7 @@ proc nimTypeOf(known: var TypeTable; sn: SchemaNode; name = ""): PNode =
of snkAtom: of snkAtom:
result = typeIdent(sn) result = typeIdent(sn)
of snkEmbedded: of snkEmbedded:
result = nimTypeOf(known, sn.embed) result = nimTypeOf(scm, known, sn.embed)
of snkLiteral: of snkLiteral:
result = case sn.value.kind # nearly verbatim from ../../preserves/src/preserves.nim result = case sn.value.kind # nearly verbatim from ../../preserves/src/preserves.nim
of pkBoolean: ident"bool" of pkBoolean: ident"bool"
@ -185,16 +189,16 @@ proc nimTypeOf(known: var TypeTable; sn: SchemaNode; name = ""): PNode =
of snkSequenceOf: of snkSequenceOf:
result = nkBracketExpr.newNode.add( result = nkBracketExpr.newNode.add(
ident"seq", ident"seq",
nimTypeOf(known, sn.child)) nimTypeOf(scm, known, sn.child))
of snkSetOf: of snkSetOf:
result = nkBracketExpr.newNode.add( result = nkBracketExpr.newNode.add(
ident"HashedSet", ident"HashedSet",
nimTypeOf(known, sn.child)) nimTypeOf(scm, known, sn.child))
of snkDictOf: of snkDictOf:
result = nkBracketExpr.newNode.add( result = nkBracketExpr.newNode.add(
ident"Table", ident"Table",
nimTypeOf(known, sn.nodes[0]), nimTypeOf(scm, known, sn.nodes[0]),
nimTypeOf(known, sn.nodes[1])) nimTypeOf(scm, known, sn.nodes[1]))
of snkRecord: of snkRecord:
case sn.nodes.len case sn.nodes.len
of 0, 1: of 0, 1:
@ -209,7 +213,7 @@ proc nimTypeOf(known: var TypeTable; sn: SchemaNode; name = ""): PNode =
let id = field.ident let id = field.ident
recList.add nkIdentDefs.newNode.add( recList.add nkIdentDefs.newNode.add(
id.accQuote.toExport, id.accQuote.toExport,
nimTypeOf(known, field, $id), nimTypeOf(scm, known, field, $id),
newEmpty()) newEmpty())
result = nn(nkObjectTy, result = nn(nkObjectTy,
newEmpty(), newEmpty(),
@ -220,23 +224,22 @@ proc nimTypeOf(known: var TypeTable; sn: SchemaNode; name = ""): PNode =
result = nkTupleTy.newNode result = nkTupleTy.newNode
for tn in sn.nodes: for tn in sn.nodes:
result.add nkIdentDefs.newNode.add( result.add nkIdentDefs.newNode.add(
tn.ident.accQuote, nimTypeOf(known, tn), newEmpty()) tn.ident.accQuote, nimTypeOf(scm, known, tn), newEmpty())
of snkDictionary: of snkDictionary:
result = nkTupleTy.newNode result = nkTupleTy.newNode
for i in countup(0, sn.nodes.high, 2): for i in countup(0, sn.nodes.high, 2):
let id = ident(sn.nodes[i+0]) let id = ident(sn.nodes[i+0])
result.add nkIdentDefs.newNode.add( result.add nkIdentDefs.newNode.add(
id.accQuote, id.accQuote,
nimTypeOf(known, sn.nodes[i+1], $id), nimTypeOf(scm, known, sn.nodes[i+1], $id),
newEmpty()) newEmpty())
of snkNamed: of snkNamed:
result = nimTypeOf(known, sn.pattern, name) result = nimTypeOf(scm, known, sn.pattern, name)
of snkRef: of snkRef:
result = typeIdent(sn) result = typeIdent(sn)
else: else:
result = nkCommentStmt.newNode result = nkCommentStmt.newNode
result.comment.add("Missing type generator for " & $sn.kind & " " & $sn) result.comment.add("Missing type generator for " & $sn.kind & " " & $sn)
result.comment = "``" & $sn & "``"
proc toConst(name: string; def: SchemaNode): Pnode = proc toConst(name: string; def: SchemaNode): Pnode =
case def.kind case def.kind
@ -266,7 +269,7 @@ proc toNimLit(sn: SchemaNode): PNode =
else: else:
raiseAssert("no Nim literal for " & $sn) raiseAssert("no Nim literal for " & $sn)
proc preserveTypeOf(known: var TypeTable; sn: SchemaNode; name = ""): PNode = proc preserveTypeOf(scm: Schema; known: var TypeTable; sn: SchemaNode; name = ""): PNode =
case sn.kind case sn.kind
of snkOr: of snkOr:
if sn.isSymbolEnum: if sn.isSymbolEnum:
@ -312,7 +315,7 @@ proc preserveTypeOf(known: var TypeTable; sn: SchemaNode; name = ""): PNode =
let id = field.ident let id = field.ident
recList.add nkIdentDefs.newNode.add( recList.add nkIdentDefs.newNode.add(
id.accQuote.toExport, id.accQuote.toExport,
nimTypeOf(known, field, $id), nimTypeOf(scm, known, field, $id),
newEmpty()) newEmpty())
result = nn(nkObjectTy, result = nn(nkObjectTy,
newEmpty(), newEmpty(),
@ -324,14 +327,14 @@ proc preserveTypeOf(known: var TypeTable; sn: SchemaNode; name = ""): PNode =
let id = field.ident let id = field.ident
recList.add nkIdentDefs.newNode.add( recList.add nkIdentDefs.newNode.add(
id.accQuote, id.accQuote,
nimTypeOf(known, field, $id), nimTypeOf(scm, known, field, $id),
newEmpty()) newEmpty())
result = nn(nkTupleTy, result = nn(nkTupleTy,
newEmpty(), newEmpty(),
newEmpty(), newEmpty(),
recList) recList)
else: else:
result = nimTypeOf(known, sn, name) result = nimTypeOf(scm, known, sn, name)
proc generateProcs(result: var seq[PNode]; name: string; sn: SchemaNode) = proc generateProcs(result: var seq[PNode]; name: string; sn: SchemaNode) =
proc exportIdent(id: string): PNode = nn(nkPostFix, ident"*", ident(id)) proc exportIdent(id: string): PNode = nn(nkPostFix, ident"*", ident(id))
@ -404,7 +407,7 @@ proc generateNimFile*(scm: Schema; path: string) =
var var
knownTypes: TypeTable knownTypes: TypeTable
typeSection = newNode nkTypeSection typeSection = newNode nkTypeSection
constSection = newNode nkConstSection constSection = newNode nkLetSection
procs: seq[PNode] procs: seq[PNode]
if scm.embeddedType == "": if scm.embeddedType == "":
typeSection.add nn(nkTypeDef, typeSection.add nn(nkTypeDef,
@ -423,12 +426,13 @@ proc generateNimFile*(scm: Schema; path: string) =
ident"PreserveGen", ident"PreserveGen",
ident"EmbeddedType")) ident"EmbeddedType"))
for name, def in scm.definitions.pairs: for name, def in scm.definitions.pairs:
if def.isConst: if isConst(scm, def):
constSection.add toConst(name, def) constSection.add toConst(name, def)
else: else:
var name = name var name = name
name[0] = name[0].toUpperAscii name[0] = name[0].toUpperAscii
let t = nimTypeOf(knownTypes, def, name) let t = nimTypeOf(scm, knownTypes, def, name)
t.comment = $def
case def.kind case def.kind
of snkAtom: of snkAtom:
knownTypes[name] = nkTypeDef.newNode.add( knownTypes[name] = nkTypeDef.newNode.add(