mirror of
https://github.com/marko-js/marko.git
synced 2026-01-18 14:55:13 +00:00
90 lines
2.7 KiB
JavaScript
90 lines
2.7 KiB
JavaScript
"use strict";
|
|
|
|
var createError = require("raptor-util/createError");
|
|
|
|
const FLAG_MIGRATOR_APPLIED = "migratorApply";
|
|
|
|
function migrateNode(node, context) {
|
|
if (node.isDetached()) {
|
|
return; //The node might have been removed from the tree
|
|
}
|
|
|
|
if (!(node.tagName || node.tagNameExpression)) {
|
|
return;
|
|
}
|
|
|
|
context.taglibLookup.forEachTagMigrator(node, migration => {
|
|
// Check to make sure a migration of a certain type is only applied once to a node
|
|
if (node.isTransformerApplied(migration)) {
|
|
return;
|
|
}
|
|
|
|
// Mark the node as have been transformed by the current migrator
|
|
node.setTransformerApplied(migration);
|
|
// Set the flag to indicate that a node was transformed
|
|
context.setFlag(FLAG_MIGRATOR_APPLIED);
|
|
context._currentNode = node;
|
|
|
|
try {
|
|
migration(node, context);
|
|
} catch (e) {
|
|
throw createError(
|
|
new Error(
|
|
'Unable to migrate template at path "' +
|
|
context.filename +
|
|
'". Error: ' +
|
|
e.message
|
|
),
|
|
e
|
|
);
|
|
}
|
|
});
|
|
}
|
|
|
|
function migrateTreeHelper(node, context) {
|
|
migrateNode(node, context);
|
|
|
|
/*
|
|
* Now process the child nodes by looping over the child nodes
|
|
* and migrating the subtree recursively
|
|
*
|
|
* NOTE: The length of the childNodes array might change as the tree is being performed.
|
|
* The checks to prevent migrators from being applied multiple times makes
|
|
* sure that this is not a problem.
|
|
*/
|
|
|
|
node.forEachChild(function(childNode) {
|
|
migrateTreeHelper(childNode, context);
|
|
});
|
|
}
|
|
|
|
function migrateTree(ast, context) {
|
|
// TODO: Consider moving this into the loop below so that root level migrations
|
|
// are also run on new nodes.
|
|
context.taglibLookup.forEachTemplateMigrator(migration => {
|
|
migration(ast, context);
|
|
});
|
|
|
|
/*
|
|
* The tree is continuously migrated until we go through an entire pass where
|
|
* there were no new nodes that needed to be migrated. This loop makes sure that
|
|
* nodes added by migrators are also migrated.
|
|
*/
|
|
do {
|
|
context.clearFlag(FLAG_MIGRATOR_APPLIED);
|
|
//Reset the flag to indicate that no migrations were yet applied to any of the nodes for this pass
|
|
migrateTreeHelper(ast, context); //Run the migrations on the tree
|
|
} while (context.isFlagSet(FLAG_MIGRATOR_APPLIED));
|
|
}
|
|
|
|
class Migrator {
|
|
migrate(ast, context) {
|
|
context.stage = "migrate";
|
|
migrateTree(ast, context);
|
|
delete context.stage;
|
|
return ast;
|
|
}
|
|
}
|
|
|
|
module.exports = Migrator;
|