| | |
| | | Object.defineProperty(exports, '__esModule', { |
| | | value: true |
| | | }); |
| | | exports.default = void 0; |
| | | exports.default = jestHoist; |
| | | |
| | | function _template() { |
| | | const data = require('@babel/template'); |
| | |
| | | }; |
| | | /* eslint-disable sort-keys */ |
| | | |
| | | var _default = () => ({ |
| | | pre({path: program}) { |
| | | this.declareJestObjGetterIdentifier = () => { |
| | | if (this.jestObjGetterIdentifier) { |
| | | return this.jestObjGetterIdentifier; |
| | | } |
| | | |
| | | this.jestObjGetterIdentifier = |
| | | program.scope.generateUidIdentifier('getJestObj'); |
| | | program.unshiftContainer('body', [ |
| | | createJestObjectGetter({ |
| | | GETTER_NAME: this.jestObjGetterIdentifier.name, |
| | | JEST_GLOBALS_MODULE_JEST_EXPORT_NAME, |
| | | JEST_GLOBALS_MODULE_NAME |
| | | }) |
| | | ]); |
| | | return this.jestObjGetterIdentifier; |
| | | }; |
| | | }, |
| | | |
| | | visitor: { |
| | | ExpressionStatement(exprStmt) { |
| | | const jestObjExpr = extractJestObjExprIfHoistable( |
| | | exprStmt.get('expression') |
| | | ); |
| | | |
| | | if (jestObjExpr) { |
| | | jestObjExpr.replaceWith( |
| | | (0, _types().callExpression)( |
| | | this.declareJestObjGetterIdentifier(), |
| | | [] |
| | | ) |
| | | ); |
| | | } |
| | | } |
| | | }, |
| | | |
| | | // in `post` to make sure we come after an import transform and can unshift above the `require`s |
| | | post({path: program}) { |
| | | const self = this; |
| | | visitBlock(program); |
| | | program.traverse({ |
| | | BlockStatement: visitBlock |
| | | }); |
| | | |
| | | function visitBlock(block) { |
| | | // use a temporary empty statement instead of the real first statement, which may itself be hoisted |
| | | const [varsHoistPoint, callsHoistPoint] = block.unshiftContainer('body', [ |
| | | (0, _types().emptyStatement)(), |
| | | (0, _types().emptyStatement)() |
| | | ]); |
| | | block.traverse({ |
| | | CallExpression: visitCallExpr, |
| | | VariableDeclarator: visitVariableDeclarator, |
| | | // do not traverse into nested blocks, or we'll hoist calls in there out to this block |
| | | blacklist: ['BlockStatement'] |
| | | }); |
| | | callsHoistPoint.remove(); |
| | | varsHoistPoint.remove(); |
| | | |
| | | function visitCallExpr(callExpr) { |
| | | var _self$jestObjGetterId; |
| | | |
| | | const { |
| | | node: {callee} |
| | | } = callExpr; |
| | | |
| | | if ( |
| | | (0, _types().isIdentifier)(callee) && |
| | | callee.name === |
| | | ((_self$jestObjGetterId = self.jestObjGetterIdentifier) === null || |
| | | _self$jestObjGetterId === void 0 |
| | | ? void 0 |
| | | : _self$jestObjGetterId.name) |
| | | ) { |
| | | const mockStmt = callExpr.getStatementParent(); |
| | | |
| | | if (mockStmt) { |
| | | const mockStmtParent = mockStmt.parentPath; |
| | | |
| | | if (mockStmtParent.isBlock()) { |
| | | const mockStmtNode = mockStmt.node; |
| | | mockStmt.remove(); |
| | | callsHoistPoint.insertBefore(mockStmtNode); |
| | | } |
| | | } |
| | | function jestHoist() { |
| | | return { |
| | | pre({path: program}) { |
| | | this.declareJestObjGetterIdentifier = () => { |
| | | if (this.jestObjGetterIdentifier) { |
| | | return this.jestObjGetterIdentifier; |
| | | } |
| | | } |
| | | |
| | | function visitVariableDeclarator(varDecl) { |
| | | if (hoistedVariables.has(varDecl.node)) { |
| | | // should be assert function, but it's not. So let's cast below |
| | | varDecl.parentPath.assertVariableDeclaration(); |
| | | const {kind, declarations} = varDecl.parent; |
| | | this.jestObjGetterIdentifier = |
| | | program.scope.generateUidIdentifier('getJestObj'); |
| | | program.unshiftContainer('body', [ |
| | | createJestObjectGetter({ |
| | | GETTER_NAME: this.jestObjGetterIdentifier.name, |
| | | JEST_GLOBALS_MODULE_JEST_EXPORT_NAME, |
| | | JEST_GLOBALS_MODULE_NAME |
| | | }) |
| | | ]); |
| | | return this.jestObjGetterIdentifier; |
| | | }; |
| | | }, |
| | | |
| | | if (declarations.length === 1) { |
| | | varDecl.parentPath.remove(); |
| | | } else { |
| | | varDecl.remove(); |
| | | } |
| | | visitor: { |
| | | ExpressionStatement(exprStmt) { |
| | | const jestObjExpr = extractJestObjExprIfHoistable( |
| | | exprStmt.get('expression') |
| | | ); |
| | | |
| | | varsHoistPoint.insertBefore( |
| | | (0, _types().variableDeclaration)(kind, [varDecl.node]) |
| | | if (jestObjExpr) { |
| | | jestObjExpr.replaceWith( |
| | | (0, _types().callExpression)( |
| | | this.declareJestObjGetterIdentifier(), |
| | | [] |
| | | ) |
| | | ); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }); |
| | | /* eslint-enable */ |
| | | }, |
| | | |
| | | exports.default = _default; |
| | | // in `post` to make sure we come after an import transform and can unshift above the `require`s |
| | | post({path: program}) { |
| | | const self = this; |
| | | visitBlock(program); |
| | | program.traverse({ |
| | | BlockStatement: visitBlock |
| | | }); |
| | | |
| | | function visitBlock(block) { |
| | | // use a temporary empty statement instead of the real first statement, which may itself be hoisted |
| | | const [varsHoistPoint, callsHoistPoint] = block.unshiftContainer( |
| | | 'body', |
| | | [(0, _types().emptyStatement)(), (0, _types().emptyStatement)()] |
| | | ); |
| | | block.traverse({ |
| | | CallExpression: visitCallExpr, |
| | | VariableDeclarator: visitVariableDeclarator, |
| | | // do not traverse into nested blocks, or we'll hoist calls in there out to this block |
| | | blacklist: ['BlockStatement'] |
| | | }); |
| | | callsHoistPoint.remove(); |
| | | varsHoistPoint.remove(); |
| | | |
| | | function visitCallExpr(callExpr) { |
| | | var _self$jestObjGetterId; |
| | | |
| | | const { |
| | | node: {callee} |
| | | } = callExpr; |
| | | |
| | | if ( |
| | | (0, _types().isIdentifier)(callee) && |
| | | callee.name === |
| | | ((_self$jestObjGetterId = self.jestObjGetterIdentifier) === |
| | | null || _self$jestObjGetterId === void 0 |
| | | ? void 0 |
| | | : _self$jestObjGetterId.name) |
| | | ) { |
| | | const mockStmt = callExpr.getStatementParent(); |
| | | |
| | | if (mockStmt) { |
| | | const mockStmtParent = mockStmt.parentPath; |
| | | |
| | | if (mockStmtParent.isBlock()) { |
| | | const mockStmtNode = mockStmt.node; |
| | | mockStmt.remove(); |
| | | callsHoistPoint.insertBefore(mockStmtNode); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | function visitVariableDeclarator(varDecl) { |
| | | if (hoistedVariables.has(varDecl.node)) { |
| | | // should be assert function, but it's not. So let's cast below |
| | | varDecl.parentPath.assertVariableDeclaration(); |
| | | const {kind, declarations} = varDecl.parent; |
| | | |
| | | if (declarations.length === 1) { |
| | | varDecl.parentPath.remove(); |
| | | } else { |
| | | varDecl.remove(); |
| | | } |
| | | |
| | | varsHoistPoint.insertBefore( |
| | | (0, _types().variableDeclaration)(kind, [varDecl.node]) |
| | | ); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }; |
| | | } |
| | | /* eslint-enable */ |