diff --git a/_extensions/cps/__init__.py b/_extensions/cps/__init__.py index 04e6d28..08f8649 100644 --- a/_extensions/cps/__init__.py +++ b/_extensions/cps/__init__.py @@ -161,15 +161,22 @@ def make_list(self, values, nodetype, classes): # ------------------------------------------------------------------------- def parse_type(self, typedesc): - if '|' in typedesc: - types = typedesc.split('|') - content = self.parse_type(types[0]) - for t in types[1:]: - content += [ - nodes.Text(' '), - nodes.inline('or', 'or', classes=['separator']), - nodes.Text(' '), - ] + self.parse_type(t) + types = jsb.split_typedesc(typedesc) + if len(types) > 1: + if len(types) == 2 and 'null' in types: + types.remove('null') + content = [ + nodes.Text('(nullable) '), + ] + self.parse_type(types[0]) + + else: + content = self.parse_type(types[0]) + for t in types[1:]: + content += [ + nodes.Text(' '), + nodes.inline('or', 'or', classes=['separator']), + nodes.Text(' '), + ] + self.parse_type(t) return content diff --git a/_packages/jsb.py b/_packages/jsb.py index 4f10b28..3bb7462 100644 --- a/_packages/jsb.py +++ b/_packages/jsb.py @@ -10,6 +10,28 @@ def decompose_typedesc(typedesc): m = re.match(r'^(list|map)[(](.*)[)]$', typedesc) return m.groups() if m else (None, typedesc) +# ============================================================================= +def split_typedesc(typedesc): + assert typedesc.count('(') == typedesc.count(')') + + types = [] + start = 0 + depth = 0 + for n in range(len(typedesc)): + if typedesc[n] == '(': + depth += 1 + elif typedesc[n] == ')': + assert depth > 0 + depth -= 1 + elif depth == 0 and typedesc[n] == '|': + types.append(typedesc[start:n]) + start = n + 1 + + types.append(typedesc[start:]) + + print(f'split typedesc {typedesc!r} => {types!r}') + return types + # ============================================================================= class JsonSchema: # ------------------------------------------------------------------------- @@ -29,8 +51,8 @@ def add_type(self, typedesc): # Type already defined; nothing to do return - if '|' in typedesc: - types = typedesc.split('|') + types = split_typedesc(typedesc) + if len(types) > 1: for t in types: self.add_type(t) diff --git a/schema.rst b/schema.rst index b7d45e2..b014b32 100644 --- a/schema.rst +++ b/schema.rst @@ -248,7 +248,7 @@ Attribute names are case sensitive. .. ---------------------------------------------------------------------------- .. cps:attribute:: definitions - :type: map(map(string)) + :type: map(map(string|null)) :context: component configuration Specifies a collection of compile definitions that must be defined