Skip to content

Commit

Permalink
CPPSDK: parameter and result handling changes (#136)
Browse files Browse the repository at this point in the history
CPPSDK:
1. parameter and result handling changes
2. anyOf type handling
3. reference schema handling
  • Loading branch information
HaseenaSainul committed Oct 18, 2023
1 parent 5695efe commit 1f2854b
Show file tree
Hide file tree
Showing 18 changed files with 87 additions and 27 deletions.
1 change: 0 additions & 1 deletion languages/cpp/templates/json-types/anyOf.c

This file was deleted.

1 change: 1 addition & 0 deletions languages/cpp/templates/json-types/anyOf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
WPEFramework::Core::JSON::VariantContainer
1 change: 1 addition & 0 deletions languages/cpp/templates/json-types/anyOfSchemaShape.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/* anyOf schema shape is supported right now */
2 changes: 2 additions & 0 deletions languages/cpp/templates/parameter-serialization/generic.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
WPEFramework::Core::JSON::Variant ${Property} = ${property};
jsonParameters.Set(_T("${property}"), ${Property});
File renamed without changes.
Empty file.
1 change: 0 additions & 1 deletion languages/cpp/templates/parameters/result.h

This file was deleted.

1 change: 1 addition & 0 deletions languages/cpp/templates/result-callback/default.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
const ${method.result.type}
1 change: 1 addition & 0 deletions languages/cpp/templates/result-callback/nonprimitive.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
const ${method.result.type}&
1 change: 1 addition & 0 deletions languages/cpp/templates/result-callback/string.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
const ${method.result.type}&
1 change: 1 addition & 0 deletions languages/cpp/templates/result/default.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
const ${method.result.type}
1 change: 0 additions & 1 deletion languages/cpp/templates/types/anyOf.c

This file was deleted.

1 change: 1 addition & 0 deletions languages/cpp/templates/types/anyOf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
std::string
1 change: 1 addition & 0 deletions languages/cpp/templates/types/anyOfSchemaShape.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/* anyOf schema shape is supported right now */
2 changes: 1 addition & 1 deletion languages/cpp/templates/types/tuple.h
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
/* ${title} */
std::pair<${type},${type}> ${title};
std::pair<${items}> ${title};
1 change: 1 addition & 0 deletions languages/javascript/templates/types/tuple-delimiter.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

10 changes: 6 additions & 4 deletions src/macrofier/engine.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ const getLinkForSchema = (schema, json, { name = '' } = {}) => {
const dirs = config.createModuleDirectories
const copySchemasIntoModules = config.copySchemasIntoModules

const type = types.getSchemaType(schema, json, { name: name, templateDir: state.typeTemplateDir, destination: state.destination, section: state.section })
const type = types.getSchemaType(schema, json, { templateDir: state.typeTemplateDir, destination: state.destination, section: state.section })

// local - insert a bogus link, that we'll update later based on final table-of-contents
if (json.components.schemas[type]) {
Expand Down Expand Up @@ -844,7 +844,7 @@ function generateSchemas(json, templates, options) {
else {
content = content.replace(/.*\$\{schema.seeAlso\}/, '')
}
// content = content.trim().length ? content.trimEnd() : content.trim()
content = content.trim().length ? content : content.trim()

const isEnum = x => x.type === 'string' && Array.isArray(x.enum) && x.title

Expand Down Expand Up @@ -1207,7 +1207,7 @@ function insertMethodMacros(template, methodObj, json, templates, examples = {})
// todo: what does prefix do in Types.mjs? need to account for it somehow
const callbackResultJsonType = event && result.schema ? types.getSchemaType(result.schema, json, { name: result.name, prefix: method.alternative, templateDir: 'json-types' }) : ''

const pullsForParamType = pullsParams ? types.getSchemaType(pullsParams, json, { destination: state.destination, section: state.section }) : ''
const pullsForParamType = pullsParams ? types.getSchemaType(pullsParams, json, { destination: state.destination, section: state.section }) : ''
const pullsForJsonType = pullsResult ? types.getSchemaType(pullsResult, json, { name: result.name, templateDir: 'json-types' }) : ''
const pullsForParamJsonType = pullsParams ? types.getSchemaType(pullsParams, json, { name: pullsParams.title , templateDir: 'json-types' }) : ''

Expand Down Expand Up @@ -1245,6 +1245,7 @@ function insertMethodMacros(template, methodObj, json, templates, examples = {})
.replace(/\$\{method\.params\.count}/g, methodObj.params ? methodObj.params.length : 0)
.replace(/\$\{if\.params\}(.*?)\$\{end\.if\.params\}/gms, method.params.length ? '$1' : '')
.replace(/\$\{if\.result\}(.*?)\$\{end\.if\.result\}/gms, resultType ? '$1' : '')
.replace(/\$\{if\.result.nonvoid\}(.*?)\$\{end\.if\.result.nonvoid\}/gms, resultType && resultType !== 'void' ? '$1' : '')
.replace(/\$\{if\.result\.properties\}(.*?)\$\{end\.if\.result\.properties\}/gms, resultParams ? '$1' : '')
.replace(/\$\{if\.params\.empty\}(.*?)\$\{end\.if\.params\.empty\}/gms, method.params.length === 0 ? '$1' : '')
.replace(/\$\{if\.signature\.empty\}(.*?)\$\{end\.if\.signature\.empty\}/gms, (method.params.length === 0 && resultType === '') ? '$1' : '')
Expand All @@ -1253,6 +1254,7 @@ function insertMethodMacros(template, methodObj, json, templates, examples = {})
.replace(/\$\{method\.params\.serialization\.with\.indent\}/g, indent(serializedParams, ' '))
// Typed signature stuff
.replace(/\$\{method\.signature\.params\}/g, types.getMethodSignatureParams(methodObj, json, { destination: state.destination, section: state.section }))
.replace(/\$\{method\.signature\.result\}/g, types.getMethodSignatureResult(methodObj, json, { destination: state.destination, section: state.section }))
.replace(/\$\{method\.context\}/g, method.context.join(', '))
.replace(/\$\{method\.context\.array\}/g, JSON.stringify(method.context))
.replace(/\$\{method\.context\.count}/g, method.context ? method.context.length : 0)
Expand Down Expand Up @@ -1287,7 +1289,7 @@ function insertMethodMacros(template, methodObj, json, templates, examples = {})
.replace(/\$\{method\.result\.type\}/g, types.getSchemaType(result.schema, json, { name: result.name, templateDir: state.typeTemplateDir, title: true, asPath: false, destination: state.destination, result: true })) //, baseUrl: options.baseUrl
.replace(/\$\{method\.result\.json\}/, types.getSchemaType(result.schema, json, { name: result.name, templateDir: 'json-types', destination: state.destination, section: state.section, title: true, code: false, link: false, asPath: false, expandEnums: false, namespace: true }))
// todo: what does prefix do?
.replace(/\$\{event\.result\.type\}/, isEventMethod(methodObj) ? types.getSchemaType(result.schema, json, { name: result.name, prefix: method.alternative, templateDir: state.typeTemplateDir, destination: state.destination, event: true, description: methodObj.result.summary, asPath: false }) : '')
.replace(/\$\{event\.result\.type\}/g, isEventMethod(methodObj) ? types.getMethodSignatureResult(event, json, { destination: state.destination, section: state.section, callback: true }) : '')
.replace(/\$\{event\.result\.json\.type\}/g, resultJsonType)
.replace(/\$\{event\.result\.json\.type\}/g, callbackResultJsonType)
.replace(/\$\{event\.pulls\.param\.name\}/g, pullsEventParamName)
Expand Down
88 changes: 69 additions & 19 deletions src/macrofier/types.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const primitives = {
"string": "string"
}

const isVoid = type => (type === 'void') ? true : false
const isPrimitiveType = type => primitives[type] ? true : false
const allocatedPrimitiveProxies = {}

Expand All @@ -54,17 +55,52 @@ const safeName = value => value.split(':').pop().replace(/[\.\-]/g, '_').replace

// TODO: This is what's left of getMethodSignatureParams. We need to figure out / handle C's `FireboltTypes_StringHandle`
function getMethodSignatureParams(method, module, { destination, callback }) {
const paramRequired = getTemplate('/parameters/default')
const paramOptional = getTemplate('/parameters/optional')
return method.params.map(param => {
let type = getSchemaType(param.schema, module, { destination, namespace : true })
if (callback && allocatedPrimitiveProxies[type]) {
type = allocatedPrimitiveProxies[type]
}

let paramRequired = ''
let jsonType = getJsonType(param.schema, module, { destination })
if (!isPrimitiveType(jsonType) && getTemplate('/parameters/nonprimitive')) {
paramRequired = getTemplate('/parameters/nonprimitive')
}
else if ((jsonType === 'string') && getTemplate('/parameters/string')) {
paramRequired = getTemplate('/parameters/string')
}
else {
paramRequired = getTemplate('/parameters/default')
}

return (param.required ? paramRequired : paramOptional).replace(/\$\{method\.param\.name\}/g, param.name).replace(/\$\{method\.param\.type\}/g, type)
}).join(', ')
}

function getMethodSignatureResult(method, module, { destination, callback, overrideRule = false }) {
let type = getSchemaType(method.result.schema, module, { destination, namespace : true })
let result = ''

if (callback) {
let jsonType = getJsonType(method.result.schema, module, { destination })

if (!isVoid(type) && !isPrimitiveType(jsonType) && getTemplate('/result-callback/nonprimitive')) {
result = getTemplate('/result-callback/nonprimitive')
}
else if ((jsonType === 'string') && getTemplate('/result-callback/string')) {
result = getTemplate('/result-callback/string')
}
else {
result = getTemplate('/result-callback/default')
}
}
else {
result = getTemplate('/result/default')
}
return result.replace(/\$\{method\.result\.type\}/g, type)
}

const getTemplate = (name) => {
if (name[0] !== '/') {
name = '/' + name
Expand Down Expand Up @@ -121,8 +157,6 @@ const insertConstMacros = (content, schema, module, name) => {
return content
}



const insertEnumMacros = (content, schema, module, name) => {
const template = content.split('\n')

Expand Down Expand Up @@ -213,7 +247,7 @@ const insertObjectMacros = (content, schema, module, title, property, options) =
}
// TODO: add language config feature for 'unknown' type
let type; // = { type: "null" }

if (schema.additionalProperties && (typeof schema.additionalProperties === 'object')) {
type = schema.additionalProperties
}
Expand All @@ -226,7 +260,7 @@ const insertObjectMacros = (content, schema, module, title, property, options) =
}
})
}

if (type) {
options2.property = prop
const schemaShape = getSchemaShape(type, module, options2)
Expand Down Expand Up @@ -265,6 +299,7 @@ const insertTupleMacros = (content, schema, module, title, options) => {
const itemsTemplate = getTemplate(path.join(options.templateDir, 'items'))
const propIndent = (content.split('\n').find(line => line.includes("${properties}")) || '').match(/^\s+/) || [''][0]
const itemsIndent = (content.split('\n').find(line => line.includes("${items}")) || '').match(/^\s+/) || [''][0]
const tupleDelimiter = getTemplate(path.join(options.templateDir, 'tuple-delimiter'))

const doMacroWork = (str, prop, i, indent) => {
const schemaShape = getSchemaShape(prop, module, options)
Expand All @@ -281,8 +316,8 @@ const insertTupleMacros = (content, schema, module, title, options) => {
.replace(/\$\{if\.optional\}(.*?)\$\{end\.if\.optional\}/gms, '')
}

content = content.replace(/\$\{properties\}/g, schema.items.map((prop, i) => doMacroWork(propTemplate, prop, i, propIndent)).join('\n'))
content = content.replace(/\$\{items\}/g, schema.items.map((prop, i) => doMacroWork(itemsTemplate, prop, i, itemsIndent)).join('\n'))
content = content.replace(/\$\{properties\}/g, schema.items.map((prop, i) => doMacroWork(propTemplate, prop, i, propIndent)).join(tupleDelimiter))
content = content.replace(/\$\{items\}/g, schema.items.map((prop, i) => doMacroWork(itemsTemplate, prop, i, itemsIndent)).join(tupleDelimiter))

return content
}
Expand All @@ -301,10 +336,13 @@ const insertPrimitiveMacros = (content, schema, module, name, templateDir) => {

const insertAnyOfMacros = (content, schema, module, name) => {
const itemTemplate = content
content = schema.anyOf.map((item, i) => itemTemplate
.replace(/\$\{type\}/g, getSchemaType(item, module))
.replace(/\$\{delimiter\}(.*?)\$\{end.delimiter\}/g, i === schema.anyOf.length - 1 ? '' : '$1')
).join('')
if (content.split('\n').find(line => line.includes("${type}"))) {
content = schema.anyOf.map((item, i) => itemTemplate
.replace(/\$\{type\}/g, getSchemaType(item, module))
.replace(/\$\{delimiter\}(.*?)\$\{end.delimiter\}/g, i === schema.anyOf.length - 1 ? '' : '$1')
).join('')
}

return content
}

Expand Down Expand Up @@ -379,14 +417,25 @@ function getSchemaShape(schema = {}, module = {}, { templateDir = 'types', name
return insertSchemaMacros(result, schema, module, theTitle, parent, property)
}
else if (schema.anyOf || schema.oneOf) {
// borrow anyOf logic, note that schema is a copy, so we're not breaking it.
if (!schema.anyOf) {
schema.anyOf = schema.oneOf
const template = getTemplate(path.join(templateDir, 'anyOfSchemaShape' + suffix))
let shape
if (template) {
shape = insertAnyOfMacros(template, schema, module, theTitle)
}
else {
// borrow anyOf logic, note that schema is a copy, so we're not breaking it.
if (!schema.anyOf) {
schema.anyOf = schema.oneOf
}
shape = insertAnyOfMacros(getTemplate(path.join(templateDir, 'anyOf' + suffix)), schema, module, theTitle)
}
if (shape) {
result = result.replace(/\$\{shape\}/g, shape)
return insertSchemaMacros(result, schema, module, theTitle, parent, property)
}
else {
return ''
}
const shape = insertAnyOfMacros(getTemplate(path.join(templateDir, 'anyOf' + suffix)), schema, module, theTitle)

result = result.replace(/\$\{shape\}/g, shape)
return insertSchemaMacros(result, schema, module, theTitle, parent, property)
}
else if (schema.allOf) {
const merger = (key) => function (a, b) {
Expand Down Expand Up @@ -500,7 +549,7 @@ function getSchemaType(schema, module, { destination, templateDir = 'types', lin
if (schema['$ref'][0] === '#') {
const refSchema = getPath(schema['$ref'], module)
const includeNamespace = (module.info.title !== getXSchemaGroup(refSchema, module))
return getSchemaType(refSchema, module, {destination, templateDir, link, title, code, asPath, event, result, expandEnums, baseUrl, namespace:includeNamespace })// { link: link, code: code, destination })
return getSchemaType(refSchema, module, {destination, templateDir, link, code, asPath, event, result, expandEnums, baseUrl, namespace:includeNamespace })// { link: link, code: code, destination })
}
else {
// TODO: This never happens... but might be worth keeping in case we link to an opaque external schema at some point?
Expand Down Expand Up @@ -680,6 +729,7 @@ export default {
setConvertTuples,
setAllocatedPrimitiveProxies,
getMethodSignatureParams,
getMethodSignatureResult,
getSchemaShape,
getSchemaType,
getSchemaInstantiation
Expand Down

0 comments on commit 1f2854b

Please sign in to comment.