Check for duplicate tag URIs at compile time

This commit is contained in:
Felix Krause 2016-04-09 21:54:49 +02:00
parent 4ca4b2c87e
commit 62fa366ac7
2 changed files with 29 additions and 2 deletions

View File

@ -15,8 +15,6 @@ an overview of already available features.
- Support generic objects - Support generic objects
- Support transient fields (i.e. fields that will not be (de-)serialized on - Support transient fields (i.e. fields that will not be (de-)serialized on
objects and tuples) objects and tuples)
- Check for and avoid name clashes when generating local tags for custom
object types.
## Developers ## Developers

View File

@ -633,9 +633,19 @@ var
## Should not be modified manually. Will be extended by ## Should not be modified manually. Will be extended by
## `serializable <#serializable,stmt,stmt>`_. ## `serializable <#serializable,stmt,stmt>`_.
static:
var
registeredUris {.compileTime.} = newSeq[string]() ## \
## Since Table doesn't really work at compile time, we also store
## registered URIs here to be able to generate a static compiler error
## when the user tries to register an URI more than once.
template setTagUriForType*(t: typedesc, uri: string): stmt = template setTagUriForType*(t: typedesc, uri: string): stmt =
## Associate the given uri with a certain type. This uri is used as YAML tag ## Associate the given uri with a certain type. This uri is used as YAML tag
## when loading and dumping values of this type. ## when loading and dumping values of this type.
when uri in registeredUris:
{. fatal: "[NimYAML] URI \"" & uri & "\" registered twice!" .}
static: registeredUris.add(uri)
let id {.gensym.} = serializationTagLibrary.registerUri(uri) let id {.gensym.} = serializationTagLibrary.registerUri(uri)
proc yamlTag*(T: typedesc[t]): TagId {.inline, raises: [].} = id proc yamlTag*(T: typedesc[t]): TagId {.inline, raises: [].} = id
## autogenerated ## autogenerated
@ -644,10 +654,29 @@ template setTagUriForType*(t: typedesc, uri: string, idName: expr): stmt =
## Like `setTagUriForType <#setTagUriForType,typedesc,string>`_, but lets ## Like `setTagUriForType <#setTagUriForType,typedesc,string>`_, but lets
## you choose a symbol for the `TagId <#TagId>`_ of the uri. This is only ## you choose a symbol for the `TagId <#TagId>`_ of the uri. This is only
## necessary if you want to implement serialization / construction yourself. ## necessary if you want to implement serialization / construction yourself.
when uri in registeredUris:
{. fatal: "[NimYAML] URI \"" & uri & "\" registered twice!" .}
static: registeredUris.add(uri)
let idName* = serializationTagLibrary.registerUri(uri) let idName* = serializationTagLibrary.registerUri(uri)
proc yamlTag*(T: typedesc[t]): TagId {.inline, raises: [].} = idName proc yamlTag*(T: typedesc[t]): TagId {.inline, raises: [].} = idName
## autogenerated ## autogenerated
static:
# standard YAML tags used by serialization
registeredUris.add("!")
registeredUris.add("?")
registeredUris.add("tag:yaml.org,2002:str")
registeredUris.add("tag:yaml.org,2002:null")
registeredUris.add("tag:yaml.org,2002:bool")
registeredUris.add("tag:yaml.org,2002:float")
registeredUris.add("tag:yaml.org,2002:timestamp")
registeredUris.add("tag:yaml.org,2002:value")
registeredUris.add("tag:yaml.org,2002:binary")
# special tags used by serialization
registeredUris.add("!nim:field")
registeredUris.add("!nim:nil:string")
registeredUris.add("!nim:nil:seq")
# tags for Nim's standard types # tags for Nim's standard types
setTagUriForType(char, "!nim:system:char", yTagNimChar) setTagUriForType(char, "!nim:system:char", yTagNimChar)
setTagUriForType(int8, "!nim:system:int8", yTagNimInt8) setTagUriForType(int8, "!nim:system:int8", yTagNimInt8)