Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@babel/plugin-transform-optional-chaining

Package Overview
Dependencies
Maintainers
4
Versions
33
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@babel/plugin-transform-optional-chaining - npm Package Compare versions

Comparing version 7.22.6 to 8.0.0-alpha.0

89

lib/index.js

@@ -1,10 +0,6 @@

'use strict';
import { declare } from '@babel/helper-plugin-utils';
import syntaxOptionalChaining from '@babel/plugin-syntax-optional-chaining';
import { template, types } from '@babel/core';
import { isTransparentExprWrapper, skipTransparentExprWrappers, skipTransparentExprWrapperNodes } from '@babel/helper-skip-transparent-expression-wrappers';
Object.defineProperty(exports, '__esModule', { value: true });
var helperPluginUtils = require('@babel/helper-plugin-utils');
var syntaxOptionalChaining = require('@babel/plugin-syntax-optional-chaining');
var core = require('@babel/core');
var helperSkipTransparentExpressionWrappers = require('@babel/helper-skip-transparent-expression-wrappers');
function willPathCastToBoolean(path) {

@@ -46,3 +42,3 @@ const maybeWrapped = findOutermostTransparentParent(path);

path.findParent(p => {
if (!helperSkipTransparentExpressionWrappers.isTransparentExprWrapper(p.node)) return true;
if (!isTransparentExprWrapper(p.node)) return true;
maybeWrapped = p;

@@ -54,4 +50,4 @@ });

function isSimpleMemberExpression(expression) {
expression = helperSkipTransparentExpressionWrappers.skipTransparentExprWrapperNodes(expression);
return core.types.isIdentifier(expression) || core.types.isSuper(expression) || core.types.isMemberExpression(expression) && !expression.computed && isSimpleMemberExpression(expression.object);
expression = skipTransparentExprWrapperNodes(expression);
return types.isIdentifier(expression) || types.isSuper(expression) || types.isMemberExpression(expression) && !expression.computed && isSimpleMemberExpression(expression.object);
}

@@ -67,3 +63,3 @@ function needsMemoize(path) {

} = optionalPath;
const childPath = helperSkipTransparentExpressionWrappers.skipTransparentExprWrappers(optionalPath.isOptionalMemberExpression() ? optionalPath.get("object") : optionalPath.get("callee"));
const childPath = skipTransparentExprWrappers(optionalPath.isOptionalMemberExpression() ? optionalPath.get("object") : optionalPath.get("callee"));
if (node.optional) {

@@ -75,6 +71,6 @@ return !scope.isStatic(childPath.node);

}
const NULLISH_CHECK = core.template.expression(`%%check%% === null || %%ref%% === void 0`);
const NULLISH_CHECK_NO_DDA = core.template.expression(`%%check%% == null`);
const NULLISH_CHECK_NEG = core.template.expression(`%%check%% !== null && %%ref%% !== void 0`);
const NULLISH_CHECK_NO_DDA_NEG = core.template.expression(`%%check%% != null`);
const NULLISH_CHECK = template.expression(`%%check%% === null || %%ref%% === void 0`);
const NULLISH_CHECK_NO_DDA = template.expression(`%%check%% == null`);
const NULLISH_CHECK_NEG = template.expression(`%%check%% !== null && %%ref%% !== void 0`);
const NULLISH_CHECK_NO_DDA_NEG = template.expression(`%%check%% != null`);
function transformOptionalChain(path, {

@@ -88,3 +84,3 @@ pureGetters,

if (scope.path.isPattern() && needsMemoize(path)) {
replacementPath.replaceWith(core.template.expression.ast`(() => ${replacementPath.node})()`);
replacementPath.replaceWith(template.expression.ast`(() => ${replacementPath.node})()`);
return;

@@ -103,6 +99,6 @@ }

optionalPath.node.type = "MemberExpression";
optionalPath = helperSkipTransparentExpressionWrappers.skipTransparentExprWrappers(optionalPath.get("object"));
optionalPath = skipTransparentExprWrappers(optionalPath.get("object"));
} else if (optionalPath.isOptionalCallExpression()) {
optionalPath.node.type = "CallExpression";
optionalPath = helperSkipTransparentExpressionWrappers.skipTransparentExprWrappers(optionalPath.get("callee"));
optionalPath = skipTransparentExprWrappers(optionalPath.get("callee"));
}

@@ -117,12 +113,12 @@ }

const node = optionals[i];
const isCall = core.types.isCallExpression(node);
const isCall = types.isCallExpression(node);
const chainWithTypes = isCall ? node.callee : node.object;
const chain = helperSkipTransparentExpressionWrappers.skipTransparentExprWrapperNodes(chainWithTypes);
const chain = skipTransparentExprWrapperNodes(chainWithTypes);
let ref;
let check;
if (isCall && core.types.isIdentifier(chain, {
if (isCall && types.isIdentifier(chain, {
name: "eval"
})) {
check = ref = chain;
node.callee = core.types.sequenceExpression([core.types.numericLiteral(0), ref]);
node.callee = types.sequenceExpression([types.numericLiteral(0), ref]);
} else if (pureGetters && isCall && isSimpleMemberExpression(chain)) {

@@ -136,10 +132,10 @@ check = ref = node.callee;

scope.push({
id: core.types.cloneNode(tmpVar)
id: types.cloneNode(tmpVar)
});
}
ref = tmpVar;
check = core.types.assignmentExpression("=", core.types.cloneNode(tmpVar), chainWithTypes);
check = types.assignmentExpression("=", types.cloneNode(tmpVar), chainWithTypes);
isCall ? node.callee = ref : node.object = ref;
}
if (isCall && core.types.isMemberExpression(chain)) {
if (isCall && types.isMemberExpression(chain)) {
if (pureGetters && isSimpleMemberExpression(chain)) {

@@ -152,4 +148,4 @@ node.callee = chainWithTypes;

let context;
if (core.types.isSuper(object)) {
context = core.types.thisExpression();
if (types.isSuper(object)) {
context = types.thisExpression();
} else {

@@ -159,3 +155,3 @@ const memoized = scope.maybeGenerateMemoised(object);

context = memoized;
chain.object = core.types.assignmentExpression("=", memoized, object);
chain.object = types.assignmentExpression("=", memoized, object);
} else {

@@ -165,9 +161,9 @@ context = object;

}
node.arguments.unshift(core.types.cloneNode(context));
node.callee = core.types.memberExpression(node.callee, core.types.identifier("call"));
node.arguments.unshift(types.cloneNode(context));
node.callee = types.memberExpression(node.callee, types.identifier("call"));
}
}
const data = {
check: core.types.cloneNode(check),
ref: core.types.cloneNode(ref)
check: types.cloneNode(check),
ref: types.cloneNode(ref)
};

@@ -181,8 +177,8 @@ Object.defineProperty(data, "ref", {

if (wrapLast) result = wrapLast(result);
const ifNullishBoolean = core.types.isBooleanLiteral(ifNullish);
const ifNullishBoolean = types.isBooleanLiteral(ifNullish);
const ifNullishFalse = ifNullishBoolean && ifNullish.value === false;
const tpl = ifNullishFalse ? noDocumentAll ? NULLISH_CHECK_NO_DDA_NEG : NULLISH_CHECK_NEG : noDocumentAll ? NULLISH_CHECK_NO_DDA : NULLISH_CHECK;
const logicalOp = ifNullishFalse ? "&&" : "||";
const check = checks.map(tpl).reduce((expr, check) => core.types.logicalExpression(logicalOp, expr, check));
replacementPath.replaceWith(ifNullishBoolean ? core.types.logicalExpression(logicalOp, check, result) : core.types.conditionalExpression(check, ifNullish, result));
const check = checks.map(tpl).reduce((expr, check) => types.logicalExpression(logicalOp, expr, check));
replacementPath.replaceWith(ifNullishBoolean ? types.logicalExpression(logicalOp, check, result) : types.conditionalExpression(check, ifNullish, result));
}

@@ -200,3 +196,3 @@ function transform(path, assumptions) {

})) {
transformOptionalChain(path, assumptions, parentPath, core.types.booleanLiteral(true));
transformOptionalChain(path, assumptions, parentPath, types.booleanLiteral(true));
} else {

@@ -208,4 +204,3 @@ let wrapLast;

wrapLast = replacement => {
var _baseRef;
const object = helperSkipTransparentExpressionWrappers.skipTransparentExprWrapperNodes(replacement.object);
const object = skipTransparentExprWrapperNodes(replacement.object);
let baseRef;

@@ -215,14 +210,13 @@ if (!assumptions.pureGetters || !isSimpleMemberExpression(object)) {

if (baseRef) {
replacement.object = core.types.assignmentExpression("=", baseRef, object);
replacement.object = types.assignmentExpression("=", baseRef, object);
}
}
return core.types.callExpression(core.types.memberExpression(replacement, core.types.identifier("bind")), [core.types.cloneNode((_baseRef = baseRef) != null ? _baseRef : object)]);
return types.callExpression(types.memberExpression(replacement, types.identifier("bind")), [types.cloneNode(baseRef ?? object)]);
};
}
transformOptionalChain(path, assumptions, path, willPathCastToBoolean(maybeWrapped) ? core.types.booleanLiteral(false) : scope.buildUndefinedNode(), wrapLast);
transformOptionalChain(path, assumptions, path, willPathCastToBoolean(maybeWrapped) ? types.booleanLiteral(false) : scope.buildUndefinedNode(), wrapLast);
}
}
var index = helperPluginUtils.declare((api, options) => {
var _api$assumption, _api$assumption2;
var index = declare((api, options) => {
api.assertVersion(7);

@@ -232,4 +226,4 @@ const {

} = options;
const noDocumentAll = (_api$assumption = api.assumption("noDocumentAll")) != null ? _api$assumption : loose;
const pureGetters = (_api$assumption2 = api.assumption("pureGetters")) != null ? _api$assumption2 : loose;
const noDocumentAll = api.assumption("noDocumentAll") ?? loose;
const pureGetters = api.assumption("pureGetters") ?? loose;
return {

@@ -249,4 +243,3 @@ name: "transform-optional-chaining",

exports["default"] = index;
exports.transform = transform;
export { index as default, transform };
//# sourceMappingURL=index.js.map

@@ -1,14 +0,7 @@

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.transform = transform;
exports.transformOptionalChain = transformOptionalChain;
var _core = require("@babel/core");
var _helperSkipTransparentExpressionWrappers = require("@babel/helper-skip-transparent-expression-wrappers");
var _util = require("./util");
import { types as t, template } from "@babel/core";
import { skipTransparentExprWrapperNodes, skipTransparentExprWrappers } from "@babel/helper-skip-transparent-expression-wrappers";
import { willPathCastToBoolean, findOutermostTransparentParent } from "./util.js";
function isSimpleMemberExpression(expression) {
expression = (0, _helperSkipTransparentExpressionWrappers.skipTransparentExprWrapperNodes)(expression);
return _core.types.isIdentifier(expression) || _core.types.isSuper(expression) || _core.types.isMemberExpression(expression) && !expression.computed && isSimpleMemberExpression(expression.object);
expression = skipTransparentExprWrapperNodes(expression);
return t.isIdentifier(expression) || t.isSuper(expression) || t.isMemberExpression(expression) && !expression.computed && isSimpleMemberExpression(expression.object);
}

@@ -24,3 +17,3 @@ function needsMemoize(path) {

} = optionalPath;
const childPath = (0, _helperSkipTransparentExpressionWrappers.skipTransparentExprWrappers)(optionalPath.isOptionalMemberExpression() ? optionalPath.get("object") : optionalPath.get("callee"));
const childPath = skipTransparentExprWrappers(optionalPath.isOptionalMemberExpression() ? optionalPath.get("object") : optionalPath.get("callee"));
if (node.optional) {

@@ -32,7 +25,7 @@ return !scope.isStatic(childPath.node);

}
const NULLISH_CHECK = _core.template.expression(`%%check%% === null || %%ref%% === void 0`);
const NULLISH_CHECK_NO_DDA = _core.template.expression(`%%check%% == null`);
const NULLISH_CHECK_NEG = _core.template.expression(`%%check%% !== null && %%ref%% !== void 0`);
const NULLISH_CHECK_NO_DDA_NEG = _core.template.expression(`%%check%% != null`);
function transformOptionalChain(path, {
const NULLISH_CHECK = template.expression(`%%check%% === null || %%ref%% === void 0`);
const NULLISH_CHECK_NO_DDA = template.expression(`%%check%% == null`);
const NULLISH_CHECK_NEG = template.expression(`%%check%% !== null && %%ref%% !== void 0`);
const NULLISH_CHECK_NO_DDA_NEG = template.expression(`%%check%% != null`);
export function transformOptionalChain(path, {
pureGetters,

@@ -45,3 +38,3 @@ noDocumentAll

if (scope.path.isPattern() && needsMemoize(path)) {
replacementPath.replaceWith(_core.template.expression.ast`(() => ${replacementPath.node})()`);
replacementPath.replaceWith(template.expression.ast`(() => ${replacementPath.node})()`);
return;

@@ -60,6 +53,6 @@ }

optionalPath.node.type = "MemberExpression";
optionalPath = (0, _helperSkipTransparentExpressionWrappers.skipTransparentExprWrappers)(optionalPath.get("object"));
optionalPath = skipTransparentExprWrappers(optionalPath.get("object"));
} else if (optionalPath.isOptionalCallExpression()) {
optionalPath.node.type = "CallExpression";
optionalPath = (0, _helperSkipTransparentExpressionWrappers.skipTransparentExprWrappers)(optionalPath.get("callee"));
optionalPath = skipTransparentExprWrappers(optionalPath.get("callee"));
}

@@ -74,12 +67,12 @@ }

const node = optionals[i];
const isCall = _core.types.isCallExpression(node);
const isCall = t.isCallExpression(node);
const chainWithTypes = isCall ? node.callee : node.object;
const chain = (0, _helperSkipTransparentExpressionWrappers.skipTransparentExprWrapperNodes)(chainWithTypes);
const chain = skipTransparentExprWrapperNodes(chainWithTypes);
let ref;
let check;
if (isCall && _core.types.isIdentifier(chain, {
if (isCall && t.isIdentifier(chain, {
name: "eval"
})) {
check = ref = chain;
node.callee = _core.types.sequenceExpression([_core.types.numericLiteral(0), ref]);
node.callee = t.sequenceExpression([t.numericLiteral(0), ref]);
} else if (pureGetters && isCall && isSimpleMemberExpression(chain)) {

@@ -93,10 +86,10 @@ check = ref = node.callee;

scope.push({
id: _core.types.cloneNode(tmpVar)
id: t.cloneNode(tmpVar)
});
}
ref = tmpVar;
check = _core.types.assignmentExpression("=", _core.types.cloneNode(tmpVar), chainWithTypes);
check = t.assignmentExpression("=", t.cloneNode(tmpVar), chainWithTypes);
isCall ? node.callee = ref : node.object = ref;
}
if (isCall && _core.types.isMemberExpression(chain)) {
if (isCall && t.isMemberExpression(chain)) {
if (pureGetters && isSimpleMemberExpression(chain)) {

@@ -109,4 +102,4 @@ node.callee = chainWithTypes;

let context;
if (_core.types.isSuper(object)) {
context = _core.types.thisExpression();
if (t.isSuper(object)) {
context = t.thisExpression();
} else {

@@ -116,3 +109,3 @@ const memoized = scope.maybeGenerateMemoised(object);

context = memoized;
chain.object = _core.types.assignmentExpression("=", memoized, object);
chain.object = t.assignmentExpression("=", memoized, object);
} else {

@@ -122,9 +115,9 @@ context = object;

}
node.arguments.unshift(_core.types.cloneNode(context));
node.callee = _core.types.memberExpression(node.callee, _core.types.identifier("call"));
node.arguments.unshift(t.cloneNode(context));
node.callee = t.memberExpression(node.callee, t.identifier("call"));
}
}
const data = {
check: _core.types.cloneNode(check),
ref: _core.types.cloneNode(ref)
check: t.cloneNode(check),
ref: t.cloneNode(ref)
};

@@ -138,14 +131,14 @@ Object.defineProperty(data, "ref", {

if (wrapLast) result = wrapLast(result);
const ifNullishBoolean = _core.types.isBooleanLiteral(ifNullish);
const ifNullishBoolean = t.isBooleanLiteral(ifNullish);
const ifNullishFalse = ifNullishBoolean && ifNullish.value === false;
const tpl = ifNullishFalse ? noDocumentAll ? NULLISH_CHECK_NO_DDA_NEG : NULLISH_CHECK_NEG : noDocumentAll ? NULLISH_CHECK_NO_DDA : NULLISH_CHECK;
const logicalOp = ifNullishFalse ? "&&" : "||";
const check = checks.map(tpl).reduce((expr, check) => _core.types.logicalExpression(logicalOp, expr, check));
replacementPath.replaceWith(ifNullishBoolean ? _core.types.logicalExpression(logicalOp, check, result) : _core.types.conditionalExpression(check, ifNullish, result));
const check = checks.map(tpl).reduce((expr, check) => t.logicalExpression(logicalOp, expr, check));
replacementPath.replaceWith(ifNullishBoolean ? t.logicalExpression(logicalOp, check, result) : t.conditionalExpression(check, ifNullish, result));
}
function transform(path, assumptions) {
export function transform(path, assumptions) {
const {
scope
} = path;
const maybeWrapped = (0, _util.findOutermostTransparentParent)(path);
const maybeWrapped = findOutermostTransparentParent(path);
const {

@@ -157,3 +150,3 @@ parentPath

})) {
transformOptionalChain(path, assumptions, parentPath, _core.types.booleanLiteral(true));
transformOptionalChain(path, assumptions, parentPath, t.booleanLiteral(true));
} else {

@@ -165,4 +158,3 @@ let wrapLast;

wrapLast = replacement => {
var _baseRef;
const object = (0, _helperSkipTransparentExpressionWrappers.skipTransparentExprWrapperNodes)(replacement.object);
const object = skipTransparentExprWrapperNodes(replacement.object);
let baseRef;

@@ -172,9 +164,9 @@ if (!assumptions.pureGetters || !isSimpleMemberExpression(object)) {

if (baseRef) {
replacement.object = _core.types.assignmentExpression("=", baseRef, object);
replacement.object = t.assignmentExpression("=", baseRef, object);
}
}
return _core.types.callExpression(_core.types.memberExpression(replacement, _core.types.identifier("bind")), [_core.types.cloneNode((_baseRef = baseRef) != null ? _baseRef : object)]);
return t.callExpression(t.memberExpression(replacement, t.identifier("bind")), [t.cloneNode(baseRef ?? object)]);
};
}
transformOptionalChain(path, assumptions, path, (0, _util.willPathCastToBoolean)(maybeWrapped) ? _core.types.booleanLiteral(false) : scope.buildUndefinedNode(), wrapLast);
transformOptionalChain(path, assumptions, path, willPathCastToBoolean(maybeWrapped) ? t.booleanLiteral(false) : scope.buildUndefinedNode(), wrapLast);
}

@@ -181,0 +173,0 @@ }

@@ -1,10 +0,3 @@

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.findOutermostTransparentParent = findOutermostTransparentParent;
exports.willPathCastToBoolean = willPathCastToBoolean;
var _helperSkipTransparentExpressionWrappers = require("@babel/helper-skip-transparent-expression-wrappers");
function willPathCastToBoolean(path) {
import { isTransparentExprWrapper } from "@babel/helper-skip-transparent-expression-wrappers";
export function willPathCastToBoolean(path) {
const maybeWrapped = findOutermostTransparentParent(path);

@@ -42,6 +35,6 @@ const {

}
function findOutermostTransparentParent(path) {
export function findOutermostTransparentParent(path) {
let maybeWrapped = path;
path.findParent(p => {
if (!(0, _helperSkipTransparentExpressionWrappers.isTransparentExprWrapper)(p.node)) return true;
if (!isTransparentExprWrapper(p.node)) return true;
maybeWrapped = p;

@@ -48,0 +41,0 @@ });

{
"name": "@babel/plugin-transform-optional-chaining",
"version": "7.22.6",
"version": "8.0.0-alpha.0",
"description": "Transform optional chaining operators into a series of nil checks",

@@ -20,20 +20,24 @@ "repository": {

"dependencies": {
"@babel/helper-plugin-utils": "^7.22.5",
"@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
"@babel/helper-plugin-utils": "^8.0.0-alpha.0",
"@babel/helper-skip-transparent-expression-wrappers": "^8.0.0-alpha.0",
"@babel/plugin-syntax-optional-chaining": "^7.8.3"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
"@babel/core": "^8.0.0-alpha.0"
},
"devDependencies": {
"@babel/core": "^7.22.6",
"@babel/helper-plugin-test-runner": "^7.22.5",
"@babel/plugin-transform-block-scoping": "^7.22.5",
"@babel/traverse": "^7.22.6"
"@babel/core": "^8.0.0-alpha.0",
"@babel/helper-plugin-test-runner": "^8.0.0-alpha.0",
"@babel/plugin-transform-block-scoping": "^8.0.0-alpha.0",
"@babel/traverse": "^8.0.0-alpha.0"
},
"engines": {
"node": ">=6.9.0"
"node": "^16.20.0 || ^18.16.0 || >=20.0.0"
},
"author": "The Babel Team (https://babel.dev/team)",
"type": "commonjs"
"exports": {
".": "./lib/index.js",
"./package.json": "./package.json"
},
"type": "module"
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc