From 9973f518941c569a06d7f2337ffcad3c772941e1 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Sat, 15 May 2021 17:09:55 +0200 Subject: [PATCH] generate-reader.uc: handle non-toplevel schema references - Handle schema references in object schema types - Derive type from referenced sub schema if type property is missing - Avoid outputting trailing white space Signed-off-by: Jo-Philipp Wich --- generate-reader.uc | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/generate-reader.uc b/generate-reader.uc index 461fce3..5a72c65 100755 --- a/generate-reader.uc +++ b/generate-reader.uc @@ -228,10 +228,13 @@ let GeneratorProto = { print: function(path, fmt, ...args) { - for (let _ in path) - print("\t"); + if (length(fmt)) { + for (let _ in path) + print("\t"); + + printf(fmt, ...args); + } - printf(fmt, ...args); print("\n"); }, @@ -322,7 +325,8 @@ let GeneratorProto = { emit_spec_validation_function: function(path, verb, propertyName, valueSpec) { - let functionName = to_method_name(verb, propertyName); + let functionName = to_method_name(verb, propertyName), + isRef = this.is_ref(valueSpec); this.print(path, 'function %s(value) {', functionName); @@ -330,6 +334,12 @@ let GeneratorProto = { this.print(path, ''); + /* Derive type from referenced subschema if possible */ + if (!exists(valueSpec, 'type') && isRef) { + let def = this.schema['$defs'][replace(isRef, '#/$defs/', '')]; + valueSpec.type = def ? def.type : null; + } + switch (valueSpec.type) { case 'array': let itemSpec = valueSpec.items, @@ -360,10 +370,6 @@ let GeneratorProto = { break; case 'object': - /* XXX: not yet */ - if (exists(valueSpec, "$ref")) - return; - if (type(valueSpec.propertyNames) == "object") { let keySpec = { type: 'string', ...(valueSpec.propertyNames) }; @@ -373,10 +379,20 @@ let GeneratorProto = { this.print(path, ''); } - if (valueSpec.additionalProperties === true) - this.print(path, ' let obj = { ...value };\n'); - else - this.print(path, ' let obj = {};\n'); + if (exists(valueSpec, "$ref")) { + let fn = to_method_name('instantiate', replace(valueSpec['$ref'], '#/$defs/', '')); + + if (valueSpec.additionalProperties === true) + this.print(path, ' let obj = { ...value, ...(%s(value)) };\n', fn); + else + this.print(path, ' let obj = %s(value);\n', fn); + } + else { + if (valueSpec.additionalProperties === true) + this.print(path, ' let obj = { ...value };\n'); + else + this.print(path, ' let obj = {};\n'); + } if (type(valueSpec.properties) == "object") { for (let objectPropertyName, propertySpec in valueSpec.properties) {