Skip to content

Commit

Permalink
Add option to include tables with parameters and I/O
Browse files Browse the repository at this point in the history
  • Loading branch information
AntoineGautier committed Oct 15, 2024
1 parent 1bbda19 commit 605e959
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 13 deletions.
16 changes: 16 additions & 0 deletions lib/cdlDoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,22 @@ const utilM2j = require('../lib/util.js')
// Object to persist the library paths
const libPath = {}

/**
* Creates an HTML table from an array of objects.
*
* @param {*} data
* @returns
*/
function createTable (data) {
if (data.length === 0) return ''
const keys = Object.keys(data[0])
const table = `<table><thead><tr>${keys.map(k => `<th>${k}</th>`).join('')}` +
'</tr></thead><tbody>'
return table + data.map(
row => `<tr>${keys.map(k => `<td>${row[k]}</td>`).join('')}</tr>`).join('') +
'</tbody></table>'
}

/**
* Determines whether a document element should be included in the documentation.
* The element must be included if:
Expand Down
90 changes: 77 additions & 13 deletions lib/expressionEvaluation.js
Original file line number Diff line number Diff line change
Expand Up @@ -420,12 +420,15 @@ function splitExpression (expression, keepOperator = false) {
*
* @todo Store in memory parameters and doc of types already processed to avoid redundant lookups.
*/
function getParametersAndBindings (classObject, jsons, fetchDoc = false, _instance, _bindings) {
const toReturn = { parameters: [], documentation: [] }
function getParametersAndBindings (classObject, jsons, fetchDoc = false, fetchVariables = false, _instance, _bindings) {
const toReturn = { parameters: [], documentation: [], variables: {} }
const components = getComponents(classObject, stringifyExpression)
const componentNames = components.map(({ identifier }) => identifier)
let fullClassName
let componentFullClassName
let classDefinition
const inputs = []
const outputs = []
const parameters = []

function prependIdentifier (identifier) {
return `${_instance ? _instance.name + '.' : ''}${identifier}`
Expand Down Expand Up @@ -475,7 +478,7 @@ function getParametersAndBindings (classObject, jsons, fetchDoc = false, _instan
})
}

function handleCompositeComponent (toReturn, component, jsons, classDefinition, fetchDoc) {
function handleCompositeComponent (toReturn, component, jsons, classDefinition, fetchDoc, fetchVariables) {
/* Variables in bindings expressions are prepended by the name of the instance
* of the class where the component with bindings is declared.
* Example:
Expand All @@ -487,6 +490,7 @@ function getParametersAndBindings (classObject, jsons, fetchDoc = false, _instan
classDefinition,
jsons,
fetchDoc,
fetchVariables,
/* _instance= */ {
name: prependIdentifier(component.identifier),
protected: component.protected,
Expand All @@ -498,9 +502,23 @@ function getParametersAndBindings (classObject, jsons, fetchDoc = false, _instan
)
toReturn.parameters.push(...componentData.parameters)
if (fetchDoc) toReturn.documentation.push(...componentData.documentation)
if (fetchVariables) {
toReturn.variables.inputs = {
...toReturn.variables.inputs,
...componentData.variables.inputs
}
toReturn.variables.outputs = {
...toReturn.variables.outputs,
...componentData.variables.outputs
}
toReturn.variables.parameters = {
...toReturn.variables.parameters,
...componentData.variables.parameters
}
}
}

fullClassName = classObject.within + '.' + getClassIdentifier(
const fullClassName = classObject.within + '.' + getClassIdentifier(
jsonQuery.getProperty(
classObject.class_definition
? pathToClassSpecifier
Expand All @@ -510,10 +528,13 @@ function getParametersAndBindings (classObject, jsons, fetchDoc = false, _instan
)

// Retrieve the documentation of the class object
// We already exclude protected components and elementary CDL blocks from the documentation
// We already exclude protected components and elementary CDL blocks for the documentation and variables
fetchDoc = fetchDoc &&
!_instance?.protected &&
!/^Buildings\.Controls\.OBC\.CDL/.test(fullClassName)
fetchVariables = fetchVariables &&
!_instance?.protected &&
!/^Buildings\.Controls\.OBC\.CDL/.test(fullClassName)

if (fetchDoc) {
const descriptionString = jsonQuery.getProperty(
Expand Down Expand Up @@ -551,19 +572,28 @@ function getParametersAndBindings (classObject, jsons, fetchDoc = false, _instan

// Retrieve the parameters and bindings of the class object
// and the documentation of each composite component

for (const component of components) {
// Local declarations of parameters and constants
if (['parameter', 'constant'].some(el => component.typePrefix?.includes(el))) {
if (fetchVariables &&
!toReturn.variables.parameters?.fullClassName &&
component.typePrefix?.includes('parameter')
) {
parameters.push({
instanceName: component.identifier,
descriptionString: component.descriptionString,
type: component.typeSpecifier.split('.').slice(-1)[0]
})
}
// Primitive types
if (primitiveTypes.includes(component.typeSpecifier)) {
handleSimpleAssignment(toReturn, component)
continue
}
fullClassName = lookupClassName(
componentFullClassName = lookupClassName(
component.typeSpecifier, classObject.within, classObject.fullMoFilePath
)
classDefinition = getClassDefinition(fullClassName, jsons, classObject)
classDefinition = getClassDefinition(componentFullClassName, jsons, classObject)
if (classDefinition == null) continue
// Enumeration types
if (classDefinition.class_prefixes?.includes('type')) {
Expand All @@ -573,18 +603,52 @@ function getParametersAndBindings (classObject, jsons, fetchDoc = false, _instan
// Record types
// parameter Record p(q=1) → Store p.q = 1 → need to process as any other composite class instance
if (classDefinition.class_prefixes?.includes('record')) {
handleCompositeComponent(toReturn, component, jsons, classDefinition, /* fetchDoc= */ false)
handleCompositeComponent(toReturn, component, jsons, classDefinition,
/* fetchDoc= */ false, /* fetchDoc= */ false) // No documentation and variables from record definitions
continue
}
} else if ( // Input connectors
fetchVariables &&
!toReturn.variables.inputs?.fullClassName &&
/\.CDL\.Interfaces\..*Input$/.test(component.typeSpecifier)) {
inputs.push({
instanceName: component.identifier,
descriptionString: component.descriptionString,
type: component.typeSpecifier.split('.').slice(-1)[0].replace('Input', '')
})
} else if ( // Output connectors
fetchVariables &&
!toReturn.variables.outputs?.fullClassName &&
/\.CDL\.Interfaces\..*Output$/.test(component.typeSpecifier)) {
outputs.push({
instanceName: component.identifier,
descriptionString: component.descriptionString,
type: component.typeSpecifier.split('.').slice(-1)[0].replace('Output', '')
})
} else if ( // Instances of non primitive types (composite components) excluding I/O
!(['input', 'output'].some(el => component.typePrefix?.includes(el))) &&
!/\.CDL\.Interfaces\..*(Input|Output)$/.test(component.typeSpecifier) &&
!primitiveTypes.includes(component.type_specifier)
) {
fullClassName = lookupClassName(component.typeSpecifier, classObject.within, classObject.fullMoFilePath)
classDefinition = getClassDefinition(fullClassName, jsons, classObject)
componentFullClassName = lookupClassName(component.typeSpecifier, classObject.within, classObject.fullMoFilePath)
classDefinition = getClassDefinition(componentFullClassName, jsons, classObject)
if (classDefinition == null) continue
handleCompositeComponent(toReturn, component, jsons, classDefinition, fetchDoc)
handleCompositeComponent(toReturn, component, jsons, classDefinition, fetchDoc, fetchVariables)
}
}

if (fetchVariables) {
toReturn.variables.inputs = {
...toReturn.variables.inputs,
[fullClassName]: inputs
}
toReturn.variables.outputs = {
...toReturn.variables.outputs,
[fullClassName]: outputs
}
toReturn.variables.parameters = {
...toReturn.variables.parameters,
[fullClassName]: parameters
}
}

Expand Down

0 comments on commit 605e959

Please sign in to comment.