Helper function to replace supers in JavaScript class transformations for Babel compiler
npx @tessl/cli install tessl/npm-babel-helper-replace-supers@6.24.0babel-helper-replace-supers is a specialized Babel transformation helper that converts ES6+ class super expressions into ES5-compatible code. It handles complex super usage patterns including method calls, property access, and assignments, providing both strict and loose transformation modes for different JavaScript environments.
npm install babel-helper-replace-supersimport ReplaceSupers from "babel-helper-replace-supers";For CommonJS:
const ReplaceSupers = require("babel-helper-replace-supers");import ReplaceSupers from "babel-helper-replace-supers";
// Inside a Babel plugin visitor for class methods
ClassMethod(path, state) {
const isConstructor = path.node.kind === "constructor";
const replaceSupers = new ReplaceSupers({
forceSuperMemoisation: isConstructor,
methodPath: path,
methodNode: path.node,
objectRef: state.classRef,
superRef: state.superName,
isStatic: path.node.static,
isLoose: state.isLoose,
scope: state.scope,
file: state.file
}, true);
// Transform all super expressions in the method
replaceSupers.replace();
// Check if any super expressions were found
if (replaceSupers.hasSuper) {
// Handle post-transformation logic
}
}babel-helper-replace-supers uses Babel's traversal system to locate and transform super expressions. It supports two transformation modes:
_get, _set) for robust super property accessThe transformation handles various super patterns including method calls, property access, assignments, and update expressions, converting them to ES5-compatible prototype-based code.
Main transformation class that handles super expression replacement in JavaScript class methods.
/**
* Creates a new ReplaceSupers instance for transforming super expressions
* @param {Object} opts - Configuration options
* @param {boolean} [inClass=false] - Whether the transformation is happening inside a class
*/
class ReplaceSupers {
constructor(opts, inClass = false);
// Configuration properties
forceSuperMemoisation: boolean;
methodPath: NodePath;
methodNode: Object;
superRef: Object;
isStatic: boolean;
hasSuper: boolean;
inClass: boolean;
isLoose: boolean;
scope: Scope;
file: any;
opts: Object;
// Collection arrays populated during traversal
bareSupers: Array<NodePath>;
returns: Array<NodePath>;
thises: Array<NodePath>;
/**
* Gets reference to the class object
* @returns {Object} Class object reference
*/
getObjectRef(): Object;
/**
* Creates call expression to set a super class property
* @param {Object} property - Property identifier or expression
* @param {Object} value - Value to assign
* @param {boolean} isComputed - Whether property access is computed
* @returns {Object} CallExpression AST node for setting super property
*/
setSuperProperty(property: Object, value: Object, isComputed: boolean): Object;
/**
* Creates call expression to get a super class property value
* @param {Object} property - Property identifier or expression
* @param {boolean} isComputed - Whether property access is computed
* @returns {Object} CallExpression AST node for getting super property
*/
getSuperProperty(property: Object, isComputed: boolean): Object;
/**
* Main method to traverse and replace super expressions in the method
* Performs transformation in-place on the AST
*/
replace(): void;
/**
* Handles super property access in loose transformation mode
* @param {Object} id - Identifier being accessed
* @param {Object} parent - Parent AST node
* @returns {Object|undefined} Replacement expression or undefined
*/
getLooseSuperProperty(id: Object, parent: Object): Object | undefined;
/**
* Handles super expressions in loose mode during traversal
* @param {NodePath} path - Current traversal path
* @returns {boolean|Object|undefined} Replacement result
*/
looseHandle(path: NodePath): boolean | Object | undefined;
/**
* Handles assignment expressions involving super properties
* @param {Object|null} ref - Reference identifier (can be null)
* @param {NodePath} path - Current traversal path
* @param {Object} node - Assignment expression node
* @returns {Object|Array} Replacement expression or array of statements
*/
specHandleAssignmentExpression(ref: Object | null, path: NodePath, node: Object): Object | Array;
/**
* Main handler for super expressions in strict mode during traversal
* @param {NodePath} path - Current traversal path
* @returns {Object|Array|boolean|undefined} Replacement result
*/
specHandle(path: NodePath): Object | Array | boolean | undefined;
/**
* Optimizes super method call expressions using babel-helper-optimise-call-expression
* @param {Object} callee - Function being called
* @param {Array} args - Arguments to the call
* @returns {Object} Optimized call expression
*/
optimiseCall(callee: Object, args: Array): Object;
}
// Babel traverse types (imported from babel-traverse)
interface NodePath {
node: Object;
parent: Object;
traverse(visitor: Object, state: any): void;
// ... other NodePath methods
}
interface Scope {
generateUidIdentifier(name: string): Object;
// ... other Scope methods
}Configuration object for the ReplaceSupers constructor:
interface ReplaceSupersOptions {
/** Force memoization of super references */
forceSuperMemoisation: boolean;
/** Babel traverse NodePath for the method being processed */
methodPath: NodePath;
/** Babel AST node representing the method */
methodNode: Object;
/** Reference to the super class */
superRef: Object;
/** Whether the method is static */
isStatic: boolean;
/** Whether to use loose transformation mode */
isLoose: boolean;
/** Babel file object */
file: any;
/** Reference to the class object (alternative to getObjetRef function) */
objectRef?: Object;
/** Function to get the class object reference (note: typo in source code - 'getObjetRef' missing 'c') */
getObjetRef?: Function;
}
// Note: The 'scope' property is automatically derived from methodPath.scope and doesn't need to be provided in optionsInput:
class Child extends Parent {
method() {
return super.parentMethod(arg);
}
}Strict Mode Output:
// Uses _get helper function
_get(Object.getPrototypeOf(Child.prototype), "parentMethod", this).call(this, arg)Loose Mode Output:
// Direct prototype access
Parent.prototype.parentMethod.call(this, arg)Input:
class Child extends Parent {
method() {
return super.parentProperty;
}
}Strict Mode Output:
_get(Object.getPrototypeOf(Child.prototype), "parentProperty", this)Input:
class Child extends Parent {
method() {
super.parentProperty = value;
}
}Strict Mode Output:
_set(Object.getPrototypeOf(Child.prototype), "parentProperty", value, this)The transformation validates super usage and throws errors for:
super without method call or property access (throws "classesIllegalBareSuper" message)babel-helper-replace-supers depends on several Babel packages:
babel-helper-optimise-call-expression - For optimizing function callsbabel-traverse - For AST traversal (NodePath, Scope types)babel-types - For AST node creation and type checkingbabel-messages - For error messagesbabel-template - For AST template generationbabel-runtime - For runtime helpers