diff --git a/packages/ember-template-compiler/lib/system/compile-options.js b/packages/ember-template-compiler/lib/system/compile-options.js index bb1deaaa862..8652309da12 100644 --- a/packages/ember-template-compiler/lib/system/compile-options.js +++ b/packages/ember-template-compiler/lib/system/compile-options.js @@ -16,48 +16,68 @@ export default function compileOptions(_options) { options.plugins = { ast: [...USER_PLUGINS, ...PLUGINS] }; } else { let potententialPugins = [...USER_PLUGINS, ...PLUGINS]; + let providedPlugins = options.plugins.ast.map(plugin => wrapLegacyPluginIfNeeded(plugin)); let pluginsToAdd = potententialPugins.filter((plugin) => { return options.plugins.ast.indexOf(plugin) === -1; }); - options.plugins.ast = options.plugins.ast.slice().concat(pluginsToAdd); + options.plugins.ast = providedPlugins.concat(pluginsToAdd); } return options; } -export function registerPlugin(type, _plugin) { - if (type !== 'ast') { - throw new Error(`Attempting to register ${_plugin} as "${type}" which is not a valid Glimmer plugin type.`); - } - - let plugin; +function wrapLegacyPluginIfNeeded(_plugin) { + let plugin = _plugin; if (_plugin.prototype && _plugin.prototype.transform) { plugin = (env) => { + let pluginInstantiated = false; + return { name: _plugin.constructor && _plugin.constructor.name, visitors: { Program(node) { - let plugin = new _plugin(env); + if (!pluginInstantiated) { + + pluginInstantiated = true; + let plugin = new _plugin(env); - plugin.syntax = env.syntax; + plugin.syntax = env.syntax; - return plugin.transform(node); + return plugin.transform(node); + } } } - }; + }; }; - } else { - plugin = _plugin; + + plugin.__raw = _plugin; } + return plugin; +} + +export function registerPlugin(type, _plugin) { + if (type !== 'ast') { + throw new Error(`Attempting to register ${_plugin} as "${type}" which is not a valid Glimmer plugin type.`); + } + + for (let i = 0; i < USER_PLUGINS.length; i++) { + let PLUGIN = USER_PLUGINS[i]; + if (PLUGIN === _plugin || PLUGIN.__raw === _plugin) { + return; + } + } + + let plugin = wrapLegacyPluginIfNeeded(_plugin); + USER_PLUGINS = [plugin, ...USER_PLUGINS]; } -export function removePlugin(type, PluginClass) { +export function unregisterPlugin(type, PluginClass) { if (type !== 'ast') { throw new Error(`Attempting to unregister ${PluginClass} as "${type}" which is not a valid Glimmer plugin type.`); } - USER_PLUGINS = USER_PLUGINS.filter((plugin) => plugin !== PluginClass); + USER_PLUGINS = USER_PLUGINS.filter((plugin) => plugin !== PluginClass && plugin.__raw !== PluginClass); } diff --git a/packages/ember-template-compiler/tests/system/compile_options_test.js b/packages/ember-template-compiler/tests/system/compile_options_test.js index d678b222507..4f89be482dc 100644 --- a/packages/ember-template-compiler/tests/system/compile_options_test.js +++ b/packages/ember-template-compiler/tests/system/compile_options_test.js @@ -17,3 +17,4 @@ QUnit.test('has default AST plugins', function(assert) { assert.ok(plugins.indexOf(plugin) > -1, `includes ${plugin}`); } }); +