An AST migration transforms an abstract syntax tree from a DSL’s pre-change structure into its post-change structure. It keeps existing DSL content usable when structural changes would otherwise make it invalid. section 10.3.2 section 10.4
Apply a migration as a versioned transformation:
- Check that the AST’s version ID matches one of the migration’s “from” version IDs. section 10.3.2
- Traverse the tree, typically depth-first, and transform each affected concept or property. section 10.3.2
- Update the DSL content’s version ID to the migration’s “to” version after transformation. section 10.3.2
- Prefer a modified copy when mutating the existing AST would be undesirable. section 10.3.2
Renaming and reshaping a concept
A migration can rename the Data Attribute concept to Attribute and move its “initial value” property to “value”. The transformation changes the concept name, copies the property value, and deletes the old property without losing the stored data. section 10.3.2
Listing 10.1 The implementation of an AST migration
const { isAstObject } = require("../common/ast")
const modifyDataAttribute = (value) => {
if (isAstObject(value)) {
const { settings } = value
for (const propertyName in settings) {
modifyDataAttribute(settings[propertyName])
}
if (value.concept === "Data Attribute") {
value.concept = "Attribute" #1
settings["value"] =
settings["initial value"] #2
delete settings["initial value"]
}
}
if (Array.isArray(value)) {
value.forEach(modifyDataAttribute)
}
}
module.exports.modifyDataAttribute = modifyDataAttribute
The implementation recursively visits AST objects and arrays, identifies Data Attribute nodes, renames the concept, moves the property, and removes the old property. section 10.3.2
