Skip to content

Commit

Permalink
CPPSDK: support to generate implementation of methods & events for bo…
Browse files Browse the repository at this point in the history
…th dynamic and static configured templates
  • Loading branch information
HaseenaSainul committed Oct 20, 2023
1 parent 750dbe4 commit ae3cfef
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 55 deletions.
133 changes: 78 additions & 55 deletions src/macrofier/engine.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ const getTemplateTypeForMethod = (method, type, templates) => {
return getTemplate(path, templates)
}

const getTemplateForMethod = (method, templates) => {
return getTemplateTypeForMethod(method, 'methods', templates)
const getTemplateForMethod = (method, templates, templateDir) => {
return getTemplateTypeForMethod(method, templateDir, templates)
}

const getTemplateForDeclaration = (method, templates, templateDir) => {
Expand Down Expand Up @@ -495,10 +495,14 @@ const generateMacros = (obj, templates, languages, options = {}) => {
schemas: {},
types: {},
enums: {},
declarations: {}
declarations: {},
methods: {},
events: {},
methodList: '',
eventList: ''
}

Array.from(new Set(['types'].concat(config.additionalSchemaTemplates))).forEach(dir => {
Array.from(new Set(['types'].concat(config.additionalSchemaTemplates))).filter(dir => dir).forEach(dir => {
state.typeTemplateDir = dir
const schemasArray = generateSchemas(obj, templates, { baseUrl: '', section: 'schemas' }).filter(s => (options.copySchemasIntoModules || !s.uri))
macros.schemas[dir] = getTemplate('/sections/schemas', templates).replace(/\$\{schema.list\}/g, schemasArray.map(s => s.body).filter(body => body).join('\n'))
Expand All @@ -507,26 +511,32 @@ const generateMacros = (obj, templates, languages, options = {}) => {
})

state.typeTemplateDir = 'types'
const examples = generateExamples(obj, templates, languages)
const allMethodsArray = generateMethods(obj, examples, templates)
const methodsArray = allMethodsArray.filter(m => m.body && !m.event && (!options.hideExcluded || !m.excluded))
const eventsArray = allMethodsArray.filter(m => m.body && m.event && (!options.hideExcluded || !m.excluded))

const imports = generateImports(obj, templates, { destination: (options.destination ? options.destination : '') })
const initialization = generateInitialization(obj, templates)
const eventsEnum = generateEvents(obj, templates)

const methods = methodsArray.length ? getTemplate('/sections/methods', templates).replace(/\$\{method.list\}/g, methodsArray.map(m => m.body).join('\n')) : ''
const methodList = methodsArray.filter(m => m.body).map(m => m.name)
const examples = generateExamples(obj, templates, languages)
const allMethodsArray = generateMethods(obj, examples, templates)

Array.from(new Set(['declarations'].concat(config.additionalDeclarationTemplates))).forEach(dir => {
Array.from(new Set(['declarations'].concat(config.additionalDeclarationTemplates))).filter(dir => dir).forEach(dir => {
const declarationsArray = allMethodsArray.filter(m => m.declaration[dir] && (!config.excludeDeclarations || (!options.hideExcluded || !m.excluded)))
macros.declarations[dir] = declarationsArray.length ? getTemplate('/sections/declarations', templates).replace(/\$\{declaration\.list\}/g, declarationsArray.map(m => m.declaration[dir]).join('\n')) : ''
})

Array.from(new Set(['methods'].concat(config.additionalMethodTemplates))).filter(dir => dir).forEach(dir => {
const methodsArray = allMethodsArray.filter(m => m.body[dir] && !m.event && (!options.hideExcluded || !m.excluded))
macros.methods[dir] = methodsArray.length ? getTemplate('/sections/methods', templates).replace(/\$\{method.list\}/g, methodsArray.map(m => m.body[dir]).join('\n')) : ''

const eventsArray = allMethodsArray.filter(m => m.body[dir] && m.event && (!options.hideExcluded || !m.excluded))
macros.events[dir] = eventsArray.length ? getTemplate('/sections/events', templates).replace(/\$\{event.list\}/g, eventsArray.map(m => m.body[dir]).join('\n')) : ''

if (dir === 'methods') {
macros.methodList = methodsArray.filter(m => m.body).map(m => m.name)
macros.eventList = eventsArray.map(m => makeEventName(m))
}
})

const providerInterfaces = generateProviderInterfaces(obj, templates)
const events = eventsArray.length ? getTemplate('/sections/events', templates).replace(/\$\{event.list\}/g, eventsArray.map(m => m.body).join('\n')) : ''
const eventList = eventsArray.map(m => makeEventName(m))
const defaults = generateDefaults(obj, templates)

const suffix = options.destination ? options.destination.split('.').pop().trim() : ''
Expand All @@ -538,11 +548,7 @@ const generateMacros = (obj, templates, languages, options = {}) => {
Object.assign(macros, {
imports,
initialization,
events,
eventList,
eventsEnum,
methods,
methodList,
defaults,
examples,
providerInterfaces,
Expand Down Expand Up @@ -590,39 +596,48 @@ const insertMacros = (fContents = '', macros = {}) => {
fContents = fContents.replace(/\$\{if\.enums\}(.*?)\$\{end\.if\.enums\}/gms, macros.enums.types.trim() ? '$1' : '')
fContents = fContents.replace(/\$\{if\.declarations\}(.*?)\$\{end\.if\.declarations\}/gms, (macros.declarations.declarations.trim() || macros.enums.types.trim()) || macros.types.types.trim()? '$1' : '')

fContents = fContents.replace(/\$\{if\.methods\}(.*?)\$\{end\.if\.methods\}/gms, (macros.methods.trim() || macros.events.trim()) ? '$1' : '')
fContents = fContents.replace(/\$\{if\.implementations\}(.*?)\$\{end\.if\.implementations\}/gms, (macros.methods.trim() || macros.events.trim() || macros.schemas.types.trim()) ? '$1' : '')
fContents = fContents.replace(/\$\{if\.methods\}(.*?)\$\{end\.if\.methods\}/gms, (macros.methods.methods.trim() || macros.events.methods.trim()) ? '$1' : '')
fContents = fContents.replace(/\$\{if\.implementations\}(.*?)\$\{end\.if\.implementations\}/gms, (macros.methods.methods.trim() || macros.events.methods.trim() || macros.schemas.types.trim()) ? '$1' : '')

fContents = fContents.replace(/\$\{module\.list\}/g, macros.module)
fContents = fContents.replace(/\$\{module\.includes\}/g, macros.moduleInclude)
fContents = fContents.replace(/\$\{module\.includes\.private\}/g, macros.moduleIncludePrivate)
fContents = fContents.replace(/\$\{module\.init\}/g, macros.moduleInit)

fContents = fContents.replace(/\$\{if\.modules\}(.*?)\$\{end\.if\.modules\}/gms, (macros.methods.trim() || macros.events.trim()) ? '$1' : '')
fContents = fContents.replace(/\$\{if\.modules\}(.*?)\$\{end\.if\.modules\}/gms, (macros.methods.methods.trim() || macros.events.methods.trim()) ? '$1' : '')

// Output the originally supported non-configurable declarations macros
fContents = fContents.replace(/[ \t]*\/\* \$\{DECLARATIONS\} \*\/[ \t]*\n/, macros.declarations.declarations)
// Output all declarations with all dynamically configured templates
Array.from(new Set(['declarations'].concat(config.additionalDeclarationTemplates))).forEach(dir => {
Array.from(new Set(['declarations'].concat(config.additionalDeclarationTemplates))).filter(dir => dir).forEach(dir => {
['DECLARATIONS'].forEach(type => {
const regex = new RegExp('[ \\t]*\\/\\* \\$\\{' + type + '\\:' + dir + '\\} \\*\\/[ \\t]*\\n', 'g')
fContents = fContents.replace(regex, macros[type.toLowerCase()][dir])
})
})

fContents = fContents.replace(/[ \t]*\/\* \$\{METHODS\} \*\/[ \t]*\n/, macros.methods)
// Output the originally supported non-configurable methods & events macros
fContents = fContents.replace(/[ \t]*\/\* \$\{METHODS\} \*\/[ \t]*\n/, macros.methods.methods)
fContents = fContents.replace(/[ \t]*\/\* \$\{METHOD_LIST\} \*\/[ \t]*\n/, macros.methodList.join(',\n'))
fContents = fContents.replace(/[ \t]*\/\* \$\{EVENTS\} \*\/[ \t]*\n/, macros.events)
fContents = fContents.replace(/[ \t]*\/\* \$\{EVENTS\} \*\/[ \t]*\n/, macros.events.methods)
fContents = fContents.replace(/[ \t]*\/\* \$\{EVENT_LIST\} \*\/[ \t]*\n/, macros.eventList.join(','))
fContents = fContents.replace(/[ \t]*\/\* \$\{EVENTS_ENUM\} \*\/[ \t]*\n/, macros.eventsEnum)

// Output all methods & events with all dynamically configured templates
Array.from(new Set(['methods'].concat(config.additionalMethodTemplates))).filter(dir => dir).forEach(dir => {
['METHODS', 'EVENTS'].forEach(type => {
const regex = new RegExp('[ \\t]*\\/\\* \\$\\{' + type + '\\:' + dir + '\\} \\*\\/[ \\t]*\\n', 'g')
fContents = fContents.replace(regex, macros[type.toLowerCase()][dir])
})
})

// Output the originally supported non-configurable schema macros
fContents = fContents.replace(/[ \t]*\/\* \$\{SCHEMAS\} \*\/[ \t]*\n/, macros.schemas.types)
fContents = fContents.replace(/[ \t]*\/\* \$\{TYPES\} \*\/[ \t]*\n/, macros.types.types)
fContents = fContents.replace(/[ \t]*\/\* \$\{ENUMS\} \*\/[ \t]*\n/, macros.enums.types)

// Output all schemas with all dynamically configured templates
Array.from(new Set(['types'].concat(config.additionalSchemaTemplates))).forEach(dir => {
Array.from(new Set(['types'].concat(config.additionalSchemaTemplates))).filter(dir => dir).forEach(dir => {
['SCHEMAS', 'TYPES', 'ENUMS'].forEach(type => {
const regex = new RegExp('[ \\t]*\\/\\* \\$\\{' + type + '\\:' + dir + '\\} \\*\\/[ \\t]*\\n', 'g')
fContents = fContents.replace(regex, macros[type.toLowerCase()][dir])
Expand Down Expand Up @@ -1083,6 +1098,29 @@ function generateExamples(json = {}, mainTemplates = {}, languages = {}) {
return examples
}

function generateMethodResult(type, templates) {
const result = {
name: type,
body: {},
declaration: {},
}

Array.from(new Set(['declarations'].concat(config.additionalDeclarationTemplates))).filter(dir => dir).forEach(dir => {
const template = getTemplate(('/' + dir + '/' + type), templates)
if (template) {
result.declaration[dir] = template
}
})

Array.from(new Set(['methods'].concat(config.additionalMethodTemplates))).filter(dir => dir).forEach(dir => {
const template = getTemplate(('/' + dir + '/' + type), templates)
if (template) {
result.body[dir] = template
}
})
return result
}

function generateMethods(json = {}, examples = {}, templates = {}) {
const methods = compose(
option([]),
Expand All @@ -1093,59 +1131,44 @@ function generateMethods(json = {}, examples = {}, templates = {}) {
const results = reduce((acc, methodObj, i, arr) => {
const result = {
name: methodObj.name,
body: '',
body: {},
declaration: {},
excluded: methodObj.tags.find(t => t.name === 'exclude-from-sdk'),
event: isEventMethod(methodObj)
}

let template = getTemplateForMethod(methodObj, templates);
if (template && template.length) {
let javascript = insertMethodMacros(template, methodObj, json, templates, examples)
result.body = javascript
}

// Generate declarations for both dynamic and static configured templates
Array.from(new Set(['declarations'].concat(config.additionalDeclarationTemplates))).forEach(dir => {
template = getTemplateForDeclaration(methodObj, templates, dir)
Array.from(new Set(['declarations'].concat(config.additionalDeclarationTemplates))).filter(dir => dir).forEach(dir => {
const template = getTemplateForDeclaration(methodObj, templates, dir)
if (template && template.length) {
let javascript = insertMethodMacros(template, methodObj, json, templates, examples)
result.declaration[dir] = javascript
}
})

// Generate implementation of methods/events for both dynamic and static configured templates
Array.from(new Set(['methods'].concat(config.additionalMethodTemplates))).filter(dir => dir).forEach(dir => {
const template = getTemplateForMethod(methodObj, templates, dir)
if (template && template.length) {
let javascript = insertMethodMacros(template, methodObj, json, templates, examples)
result.body[dir] = javascript
}
})

acc.push(result)

return acc
}, [], methods)

// TODO: might be useful to pass in local macro for an array with all capability & provider interface names
if (json.methods && json.methods.find(isProviderInterfaceMethod)) {
results.push({
name: "provide",
body: getTemplate('/methods/provide', templates),
declaration: getTemplate('/declarations/provide', templates),
})
results.push(generateMethodResult('provide', templates))
}

// TODO: might be useful to pass in local macro for an array with all event names
if (json.methods && json.methods.find(isPublicEventMethod)) {
results.push({
name: "listen",
body: getTemplate('/methods/listen', templates),
declaration: getTemplate('/declarations/listen', templates)
})

results.push({
name: "once",
body: getTemplate('/methods/once', templates),
declaration: getTemplate('/declarations/once', templates)
})

results.push({
name: "clear",
body: getTemplate('/methods/clear', templates),
declaration: getTemplate('/declarations/clear', templates)
['listen', 'once', 'clear'].forEach(type => {
results.push(generateMethodResult(type, templates))
})
}

Expand Down
2 changes: 2 additions & 0 deletions src/macrofier/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ const macrofy = async (
convertTuplesToArraysOrObjects,
additionalSchemaTemplates,
additionalDeclarationTemplates,
additionalMethodTemplates,
excludeDeclarations,
aggregateFiles,
operators,
Expand Down Expand Up @@ -96,6 +97,7 @@ const macrofy = async (
allocatedPrimitiveProxies,
additionalSchemaTemplates,
additionalDeclarationTemplates,
additionalMethodTemplates,
excludeDeclarations,
operators
})
Expand Down
1 change: 1 addition & 0 deletions src/sdk/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ const run = async ({
allocatedPrimitiveProxies: config.allocatedPrimitiveProxies,
additionalSchemaTemplates: config.additionalSchemaTemplates,
additionalDeclarationTemplates: config.additionalDeclarationTemplates,
additionalMethodTemplates: config.additionalMethodTemplates,
excludeDeclarations: config.excludeDeclarations,
staticModuleNames: staticModuleNames,
hideExcluded: true,
Expand Down

0 comments on commit ae3cfef

Please sign in to comment.