Use ?. where it represents the intended semantics (#11512)

This commit is contained in:
Nicolò Ribaudo 2020-05-09 23:31:50 +02:00 committed by GitHub
parent aeb51f463c
commit 31b361b736
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 99 additions and 118 deletions

View File

@ -71,8 +71,9 @@ export function* findRelativeConfig(
loc,
envName,
caller,
packageData.pkg && packageData.pkg.dirname === loc
? packageToBabelConfig(packageData.pkg)
packageData.pkg?.dirname === loc
? // $FlowIgnore - packageData.pkg is not null
packageToBabelConfig((packageData.pkg: ConfigFile))
: null,
);
}

View File

@ -17,7 +17,8 @@ export type { PartialConfig } from "./partial";
const loadOptionsRunner = gensync<[mixed], Object | null>(function*(opts) {
const config = yield* loadFullConfig(opts);
return config ? config.options : null;
// NOTE: We want to return "null" explicitly, while ?. alone returns undefined
return config?.options ?? null;
});
const maybeErrback = runner => (opts: mixed, callback: Function) => {

View File

@ -25,15 +25,7 @@ type TransformFile = {
const transformFileRunner = gensync<[string, ?InputOptions], FileResult | null>(
function*(filename, opts) {
let options;
if (opts == null) {
options = { filename };
} else if (opts && typeof opts === "object") {
options = {
...opts,
filename,
};
}
const options = { ...opts, filename };
const config: ResolvedConfig | null = yield* loadConfig(options);
if (config === null) return null;

View File

@ -44,7 +44,7 @@ const blockHoistPlugin = {
let hasChange = false;
for (let i = 0; i < node.body.length; i++) {
const bodyNode = node.body[i];
if (bodyNode && bodyNode._blockHoist != null) {
if (bodyNode?._blockHoist != null) {
hasChange = true;
break;
}
@ -52,7 +52,7 @@ const blockHoistPlugin = {
if (!hasChange) return;
node.body = sortBy(node.body, function(bodyNode) {
let priority = bodyNode && bodyNode._blockHoist;
let priority = bodyNode?._blockHoist;
if (priority == null) priority = 1;
if (priority === true) priority = 2;

View File

@ -44,7 +44,7 @@ export default class Buffer {
// source string since it may be arbitrarily large after all transformations
code: this._buf.join("").trimRight(),
map: null,
rawMappings: map && map.getRawMappings(),
rawMappings: map?.getRawMappings(),
};
if (map) {
@ -315,10 +315,10 @@ export default class Buffer {
const origFilename = targetObj.filename;
targetObj.identifierName =
(prop === "start" && loc && loc.identifierName) || null;
targetObj.line = pos ? pos.line : null;
targetObj.column = pos ? pos.column : null;
targetObj.filename = (loc && loc.filename) || null;
(prop === "start" && loc?.identifierName) || null;
targetObj.line = pos?.line;
targetObj.column = pos?.column;
targetObj.filename = loc?.filename;
// We want to skip reassigning `force` if we're re-setting the same position.
if (

View File

@ -21,7 +21,7 @@ export function BlockStatement(node: Object) {
this.token("{");
this.printInnerComments(node);
const hasDirectives = node.directives && node.directives.length;
const hasDirectives = node.directives?.length;
if (node.body.length || hasDirectives) {
this.newline();

View File

@ -147,7 +147,7 @@ export function ImportDeclaration(node: Object) {
}
const specifiers = node.specifiers.slice(0);
if (specifiers && specifiers.length) {
if (specifiers?.length) {
// print "special" specifiers first
for (;;) {
const first = specifiers[0];

View File

@ -196,10 +196,7 @@ nodes.ObjectTypeCallProperty = function(
node: Object,
parent,
): ?WhitespaceObject {
if (
parent.callProperties[0] === node &&
(!parent.properties || !parent.properties.length)
) {
if (parent.callProperties[0] === node && !parent.properties?.length) {
return {
before: true,
};
@ -209,8 +206,8 @@ nodes.ObjectTypeCallProperty = function(
nodes.ObjectTypeIndexer = function(node: Object, parent): ?WhitespaceObject {
if (
parent.indexers[0] === node &&
(!parent.properties || !parent.properties.length) &&
(!parent.callProperties || !parent.callProperties.length)
!parent.properties?.length &&
!parent.callProperties?.length
) {
return {
before: true,
@ -224,9 +221,9 @@ nodes.ObjectTypeInternalSlot = function(
): ?WhitespaceObject {
if (
parent.internalSlots[0] === node &&
(!parent.properties || !parent.properties.length) &&
(!parent.callProperties || !parent.callProperties.length) &&
(!parent.indexers || !parent.indexers.length)
!parent.properties?.length &&
!parent.callProperties?.length &&
!parent.indexers?.length
) {
return {
before: true,

View File

@ -310,7 +310,7 @@ export default class Printer {
// catch up to this nodes newline if we're behind
const pos = loc ? loc[prop] : null;
if (pos && pos.line !== null) {
if (pos?.line != null) {
const count = pos.line - this._buf.getCurrentLine();
for (let i = 0; i < count; i++) {
@ -360,7 +360,7 @@ export default class Printer {
endTerminatorless(state: Object) {
this._noLineTerminator = false;
if (state && state.printed) {
if (state?.printed) {
this.dedent();
this.newline();
this.token(")");
@ -380,7 +380,7 @@ export default class Printer {
throw new ReferenceError(
`unknown node of type ${JSON.stringify(
node.type,
)} with constructor ${JSON.stringify(node && node.constructor.name)}`,
)} with constructor ${JSON.stringify(node?.constructor.name)}`,
);
}
@ -463,7 +463,7 @@ export default class Printer {
}
printJoin(nodes: ?Array, parent: Object, opts = {}) {
if (!nodes || !nodes.length) return;
if (!nodes?.length) return;
if (opts.indent) this.indent();
@ -523,7 +523,7 @@ export default class Printer {
}
printInnerComments(node, indent = true) {
if (!node.innerComments || !node.innerComments.length) return;
if (!node.innerComments?.length) return;
if (indent) this.indent();
this._printComments(node.innerComments);
if (indent) this.dedent();
@ -606,7 +606,7 @@ export default class Printer {
: `/*${comment.value}*/`;
if (isBlockComment && this.format.indent.adjustMultilineComment) {
const offset = comment.loc && comment.loc.start.column;
const offset = comment.loc?.start.column;
if (offset) {
const newlineRegex = new RegExp("\\n\\s{1," + offset + "}", "g");
val = val.replace(newlineRegex, "\n");
@ -630,7 +630,7 @@ export default class Printer {
}
_printComments(comments?: Array<Object>, inlinePureAnnotation?: boolean) {
if (!comments || !comments.length) return;
if (!comments?.length) return;
if (
inlinePureAnnotation &&

View File

@ -70,8 +70,8 @@ export function isRequired(
excludes?: Set<string>,
} = {},
) {
if (excludes && excludes.has(name)) return false;
if (includes && includes.has(name)) return true;
if (excludes?.has(name)) return false;
if (includes?.has(name)) return true;
return !targetsSupported(targets, compatData[name]);
}

View File

@ -111,7 +111,7 @@ function getLowestVersions(browsers: Array<string>): Targets {
}
function outputDecimalWarning(decimalTargets: Array<Object>): void {
if (!decimalTargets || !decimalTargets.length) {
if (!decimalTargets?.length) {
return;
}

View File

@ -108,7 +108,7 @@ function getHelperMetadata(file) {
const binding = child.scope.getBinding(exportName);
if (binding && binding.scope.path.isProgram()) {
if (binding?.scope.path.isProgram()) {
exportBindingAssignments.push(makePath(child));
}
},

View File

@ -16,7 +16,7 @@ import "./tokenizer/context";
import type { Expression, File } from "./types";
export function parse(input: string, options?: Options): File {
if (options && options.sourceType === "unambiguous") {
if (options?.sourceType === "unambiguous") {
options = {
...options,
};
@ -71,7 +71,7 @@ export { tokTypes };
function getParser(options: ?Options, input: string): Parser {
let cls = Parser;
if (options && options.plugins) {
if (options?.plugins) {
validatePlugins(options.plugins);
cls = getParserClass(options.plugins);
}

View File

@ -769,7 +769,7 @@ export default class ExpressionParser extends LValParser {
this.raise(node.start, Errors.ImportCallArity);
} else {
const importArg = node.arguments[0];
if (importArg && importArg.type === "SpreadElement") {
if (importArg?.type === "SpreadElement") {
this.raise(importArg.start, Errors.ImportCallSpreadArgument);
}
}

View File

@ -160,9 +160,9 @@ export default class LValParser extends NodeUtils {
let end = exprList.length;
if (end) {
const last = exprList[end - 1];
if (last && last.type === "RestElement") {
if (last?.type === "RestElement") {
--end;
} else if (last && last.type === "SpreadElement") {
} else if (last?.type === "SpreadElement") {
last.type = "RestElement";
const arg = last.argument;
this.toAssignable(arg);
@ -210,7 +210,7 @@ export default class LValParser extends NodeUtils {
this.toReferencedList(exprList, isParenthesizedExpr);
for (const expr of exprList) {
if (expr && expr.type === "ArrayExpression") {
if (expr?.type === "ArrayExpression") {
this.toReferencedListDeep(expr.elements);
}
}

View File

@ -13,8 +13,8 @@ class Node implements NodeBase {
this.start = pos;
this.end = 0;
this.loc = new SourceLocation(loc);
if (parser && parser.options.ranges) this.range = [pos, 0];
if (parser && parser.filename) this.loc.filename = parser.filename;
if (parser?.options.ranges) this.range = [pos, 0];
if (parser?.filename) this.loc.filename = parser.filename;
}
type: string;

View File

@ -165,7 +165,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
if (name === "__proto__" && prop.kind === "init") {
// Store the first redefinition's position
if (protoRef.used) {
if (refExpressionErrors && refExpressionErrors.doubleProto === -1) {
if (refExpressionErrors?.doubleProto === -1) {
refExpressionErrors.doubleProto = key.start;
} else {
this.raise(key.start, Errors.DuplicateProto);
@ -181,7 +181,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
stmt.type === "ExpressionStatement" &&
stmt.expression.type === "Literal" &&
typeof stmt.expression.value === "string" &&
(!stmt.expression.extra || !stmt.expression.extra.parenthesized)
!stmt.expression.extra?.parenthesized
);
}

View File

@ -2198,7 +2198,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
): $ReadOnlyArray<N.Pattern> {
for (let i = 0; i < exprList.length; i++) {
const expr = exprList[i];
if (expr && expr.type === "TypeCastExpression") {
if (expr?.type === "TypeCastExpression") {
exprList[i] = this.typeCastToParameter(expr);
}
}
@ -2216,7 +2216,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
if (
expr &&
expr.type === "TypeCastExpression" &&
(!expr.extra || !expr.extra.parenthesized) &&
!expr.extra?.parenthesized &&
(exprList.length > 1 || !isParenthesizedExpr)
) {
this.raise(expr.typeAnnotation.start, FlowErrors.TypeCastInPattern);
@ -2665,7 +2665,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
}
}
if ((jsx && jsx.error) || this.isRelational("<")) {
if (jsx?.error || this.isRelational("<")) {
state = state || this.state.clone();
let typeParameters;
@ -2690,9 +2690,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
}, state);
const arrowExpression: ?N.ArrowFunctionExpression =
arrow.node && arrow.node.type === "ArrowFunctionExpression"
? arrow.node
: null;
arrow.node?.type === "ArrowFunctionExpression" ? arrow.node : null;
if (!arrow.error && arrowExpression) return arrowExpression;
@ -2702,7 +2700,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
// If the error is recoverable, we can only re-report it if there is
// a node we can return.
if (jsx && jsx.node) {
if (jsx?.node) {
/*:: invariant(jsx.failState) */
this.state = jsx.failState;
return jsx.node;
@ -2714,7 +2712,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
return arrowExpression;
}
if (jsx && jsx.thrown) throw jsx.error;
if (jsx?.thrown) throw jsx.error;
if (arrow.thrown) throw arrow.error;
/*:: invariant(typeParameters) */

View File

@ -261,7 +261,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
checkExport(node: N.ExportNamedDeclaration): void {
const { specifiers } = node;
if (specifiers && specifiers.length) {
if (specifiers?.length) {
node.specifiers = specifiers.filter(
node => node.exported.type === "Placeholder",
);

View File

@ -2340,7 +2340,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
}
}
if (!(jsx && jsx.error) && !this.isRelational("<")) {
if (!jsx?.error && !this.isRelational("<")) {
return super.parseMaybeAssign(...args);
}
@ -2362,7 +2362,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
}
// Correct TypeScript code should have at least 1 type parameter, but don't crash on bad code.
if (typeParameters && typeParameters.params.length !== 0) {
if (typeParameters?.params.length !== 0) {
this.resetStartLocationFromNode(expr, typeParameters);
}
expr.typeParameters = typeParameters;
@ -2384,7 +2384,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
if (!typeCast.error) return typeCast.node;
}
if (jsx && jsx.node) {
if (jsx?.node) {
/*:: invariant(jsx.failState) */
this.state = jsx.failState;
return jsx.node;
@ -2396,17 +2396,17 @@ export default (superClass: Class<Parser>): Class<Parser> =>
return arrow.node;
}
if (typeCast && typeCast.node) {
if (typeCast?.node) {
/*:: invariant(typeCast.failState) */
this.state = typeCast.failState;
return typeCast.node;
}
if (jsx && jsx.thrown) throw jsx.error;
if (jsx?.thrown) throw jsx.error;
if (arrow.thrown) throw arrow.error;
if (typeCast && typeCast.thrown) throw typeCast.error;
if (typeCast?.thrown) throw typeCast.error;
throw (jsx && jsx.error) || arrow.error || (typeCast && typeCast.error);
throw jsx?.error || arrow.error || typeCast?.error;
}
// Handle type assertions
@ -2616,7 +2616,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
): $ReadOnlyArray<?N.Expression> {
for (let i = 0; i < exprList.length; i++) {
const expr = exprList[i];
if (expr && expr.type === "TSTypeCastExpression") {
if (expr?.type === "TSTypeCastExpression") {
this.raise(expr.start, TSErrors.UnexpectedTypeAnnotation);
}
}

View File

@ -225,7 +225,7 @@ export default class Tokenizer extends LocationParser {
nextToken(): void {
const curContext = this.curContext();
if (!curContext || !curContext.preserveSpace) this.skipSpace();
if (!curContext?.preserveSpace) this.skipSpace();
this.state.octalPositions = [];
this.state.start = this.state.pos;

View File

@ -95,7 +95,7 @@ function applyMethodDecorators(path, state) {
}
function hasMethodDecorators(body) {
return body.some(node => node.decorators && node.decorators.length);
return body.some(node => node.decorators?.length);
}
/**

View File

@ -21,7 +21,7 @@ export default declare(api => {
visitor: {
"DirectiveLiteral|StringLiteral"({ node }) {
const { extra } = node;
if (!extra || !extra.raw) return;
if (!extra?.raw) return;
extra.raw = extra.raw.replace(regex, replace);
},

View File

@ -127,7 +127,7 @@ function isInLoop(path) {
path => path.isLoop() || path.isFunction(),
);
return loopOrFunctionParent && loopOrFunctionParent.isLoop();
return loopOrFunctionParent?.isLoop();
}
function convertBlockScopedToVar(

View File

@ -20,7 +20,7 @@ export default declare(api => {
comments = generateComment(ofPath, optional),
keepType = false,
}) {
if (!toPath || !toPath.node) {
if (!toPath?.node) {
toPath = ofPath.getPrevSibling();
where = "trailing";
}
@ -36,7 +36,7 @@ export default declare(api => {
comments = [comments];
}
comments = comments.map(commentFromString);
if (!keepType && ofPath && ofPath.node) {
if (!keepType && ofPath?.node) {
// Removes the node at `ofPath` while conserving the comments attached
// to it.
const node = ofPath.node;

View File

@ -381,7 +381,7 @@ export default declare((api, options) => {
}
} else {
const specifiers = path.node.specifiers;
if (specifiers && specifiers.length) {
if (specifiers?.length) {
if (path.node.source) {
pushModule(path.node.source.value, "exports", specifiers);
path.remove();

View File

@ -59,7 +59,7 @@ export default declare(api => {
const attributes = path.container.openingElement.attributes;
for (let i = 0; i < attributes.length; i++) {
const name = attributes[i].name;
if (name && name.name === TRACE_ID) {
if (name?.name === TRACE_ID) {
// The __source attribute already exists
return;
}

View File

@ -8,7 +8,7 @@ import { typeAnnotationToString } from "./helpers";
import getRuntimePath from "./get-runtime-path";
function supportsStaticESM(caller) {
return !!(caller && caller.supportsStaticESM);
return !!caller?.supportsStaticESM;
}
export default declare((api, options, dirname) => {

View File

@ -199,15 +199,15 @@ export const getPolyfillPlugins = ({
};
function supportsStaticESM(caller) {
return !!(caller && caller.supportsStaticESM);
return !!caller?.supportsStaticESM;
}
function supportsDynamicImport(caller) {
return !!(caller && caller.supportsDynamicImport);
return !!caller?.supportsDynamicImport;
}
function supportsTopLevelAwait(caller) {
return !!(caller && caller.supportsTopLevelAwait);
return !!caller?.supportsTopLevelAwait;
}
export default declare((api, opts) => {
@ -232,7 +232,7 @@ export default declare((api, opts) => {
// TODO: remove this in next major
let hasUglifyTarget = false;
if (optionsTargets && optionsTargets.uglify) {
if (optionsTargets?.uglify) {
hasUglifyTarget = true;
delete optionsTargets.uglify;
@ -242,7 +242,7 @@ export default declare((api, opts) => {
console.log("");
}
if (optionsTargets && optionsTargets.esmodules && optionsTargets.browsers) {
if (optionsTargets?.esmodules && optionsTargets.browsers) {
console.log("");
console.log(
"@babel/preset-env: esmodules and browsers targets have been specified together.",
@ -269,10 +269,9 @@ export default declare((api, opts) => {
transformations: moduleTransformations,
// TODO: Remove the 'api.caller' check eventually. Just here to prevent
// unnecessary breakage in the short term for users on older betas/RCs.
shouldTransformESM:
modules !== "auto" || !api.caller || !api.caller(supportsStaticESM),
shouldTransformESM: modules !== "auto" || !api.caller?.(supportsStaticESM),
shouldTransformDynamicImport:
modules !== "auto" || !api.caller || !api.caller(supportsDynamicImport),
modules !== "auto" || !api.caller?.(supportsDynamicImport),
shouldParseTopLevelAwait: !api.caller || api.caller(supportsTopLevelAwait),
});

View File

@ -94,7 +94,7 @@ export default function(
const { deopt, value } = path.evaluate();
if (value !== undefined) {
instanceType = getType(value);
} else if (deopt && deopt.isIdentifier()) {
} else if (deopt?.isIdentifier()) {
builtIn = deopt.node.name;
}
}

View File

@ -207,7 +207,7 @@ function onDOMContentLoaded() {
// Listen for load event if we're in a browser and then kick off finding and
// running of scripts with "text/babel" type.
if (typeof window !== "undefined" && window && window.addEventListener) {
if (typeof window !== "undefined" && window?.addEventListener) {
window.addEventListener("DOMContentLoaded", onDOMContentLoaded, false);
}

View File

@ -112,7 +112,7 @@ function placeholderVisitorHandler(
state.isLegacyRef.value &&
(state.placeholderPattern === false ||
!(state.placeholderPattern || PATTERN).test(name)) &&
(!state.placeholderWhitelist || !state.placeholderWhitelist.has(name))
!state.placeholderWhitelist?.has(name)
) {
return;
}

View File

@ -31,7 +31,7 @@ export default class TraversalContext {
// check if we're going to traverse into this node
const keys: ?Array<string> = t.VISITOR_KEYS[node.type];
if (!keys || !keys.length) return false;
if (!keys?.length) return false;
// we need to traverse into this node so ensure that it has children to traverse into!
for (const key of keys) {

View File

@ -236,7 +236,7 @@ export function setup(parentPath, container, listKey, key) {
export function setKey(key) {
this.key = key;
this.node = this.container[this.key];
this.type = this.node && this.node.type;
this.type = this.node?.type;
}
export function requeue(pathToQueue = this) {

View File

@ -170,7 +170,7 @@ function hoistFunctionEnvironment(
p.isClassProperty({ static: false })
);
});
const inConstructor = thisEnvFn && thisEnvFn.node.kind === "constructor";
const inConstructor = thisEnvFn?.node.kind === "constructor";
if (thisEnvFn.isClassProperty()) {
throw fnPath.buildCodeFrameError(

View File

@ -160,7 +160,7 @@ function _evaluate(path, state) {
return deopt(binding.path, state);
}
if (binding && binding.hasValue) {
if (binding?.hasValue) {
return binding.value;
} else {
if (node.name === "undefined") {

View File

@ -53,7 +53,7 @@ export function _getTypeAnnotation(): ?Object {
}
inferer = inferers[this.parentPath.type];
if (inferer && inferer.validParent) {
if (inferer?.validParent) {
return this.parentPath.getTypeAnnotation();
}
}

View File

@ -10,7 +10,7 @@ export function VariableDeclarator() {
let type = init.getTypeAnnotation();
if (type && type.type === "AnyTypeAnnotation") {
if (type?.type === "AnyTypeAnnotation") {
// Detect "var foo = Array()" calls so we can optimize for arrays vs iterables.
if (
init.isCallExpression() &&

View File

@ -7,7 +7,7 @@ export function remove() {
this._assertUnremoved();
this.resync();
if (!this.opts || !this.opts.noScope) {
if (!this.opts?.noScope) {
this._removeFromScope();
}

View File

@ -196,7 +196,7 @@ export function _replaceWith(node) {
t.validate(this.parent, this.key, node);
}
this.debug(`Replace with ${node && node.type}`);
this.debug(`Replace with ${node?.type}`);
this.node = this.container[this.key] = node;
}
@ -217,7 +217,7 @@ export function replaceExpressionWithStatements(nodes: Array<Object>) {
}
const functionParent = this.getFunctionParent();
const isParentAsync = functionParent && functionParent.is("async");
const isParentAsync = functionParent?.is("async");
const container = t.arrowFunctionExpression([], t.blockStatement(nodes));

View File

@ -294,7 +294,7 @@ export default class Scope {
const cached = scopeCache.get(node);
// Sometimes, a scopable path is placed higher in the AST tree.
// In these cases, have to create a new Scope.
if (cached && cached.path === path) {
if (cached?.path === path) {
return cached;
}
scopeCache.set(node, this);
@ -322,7 +322,7 @@ export default class Scope {
get parent() {
const parent = this.path.findParent(p => p.isScope());
return parent && parent.scope;
return parent?.scope;
}
get parentBlock() {
@ -523,7 +523,7 @@ export default class Scope {
toArray(node: Object, i?: number) {
if (t.isIdentifier(node)) {
const binding = this.getBinding(node.name);
if (binding && binding.constant && binding.path.isGenericType("Array")) {
if (binding?.constant && binding.path.isGenericType("Array")) {
return node;
}
}
@ -1014,13 +1014,12 @@ export default class Scope {
}
getBindingIdentifier(name: string) {
const info = this.getBinding(name);
return info && info.identifier;
return this.getBinding(name)?.identifier;
}
getOwnBindingIdentifier(name: string) {
const binding = this.bindings[name];
return binding && binding.identifier;
return binding?.identifier;
}
hasOwnBinding(name: string) {
@ -1038,7 +1037,7 @@ export default class Scope {
}
parentHasBinding(name: string, noGlobals?) {
return this.parent && this.parent.hasBinding(name, noGlobals);
return this.parent?.hasBinding(name, noGlobals);
}
/**
@ -1060,10 +1059,7 @@ export default class Scope {
removeBinding(name: string) {
// clear literal binding
const info = this.getBinding(name);
if (info) {
info.scope.removeOwnBinding(name);
}
this.getBinding(name)?.scope.removeOwnBinding(name);
// clear uids with this name - https://github.com/babel/babel/issues/2101
let scope = this;

View File

@ -3,7 +3,7 @@ import isNode from "../validators/isNode";
export default function assertNode(node?: Object): void {
if (!isNode(node)) {
const type = (node && node.type) || JSON.stringify(node);
const type = node?.type ?? JSON.stringify(node);
throw new TypeError(`Not a valid node of type "${(type: any)}"`);
}
}

View File

@ -14,7 +14,7 @@ export default function toSequenceExpression(
nodes: Array<Object>,
scope: Scope,
): ?Object {
if (!nodes || !nodes.length) return;
if (!nodes?.length) return;
const declars = [];
const result = gatherSequenceExpressions(nodes, scope, declars);

View File

@ -18,7 +18,7 @@ export const PLACEHOLDERS_ALIAS: { [string]: Array<string> } = {
for (const type of PLACEHOLDERS) {
const alias = ALIAS_KEYS[type];
if (alias && alias.length) PLACEHOLDERS_ALIAS[type] = alias;
if (alias?.length) PLACEHOLDERS_ALIAS[type] = alias;
}
export const PLACEHOLDERS_FLIPPED_ALIAS: { [string]: Array<string> } = {};

View File

@ -110,7 +110,7 @@ export function assertNodeType(...types: Array<string>): Validator {
node.type
} expected node to be of a type ${JSON.stringify(
types,
)} but instead got ${JSON.stringify(val && val.type)}`,
)} but instead got ${JSON.stringify(val?.type)}`,
);
}
@ -133,7 +133,7 @@ export function assertNodeOrValueType(...types: Array<string>): Validator {
node.type
} expected node to be of a type ${JSON.stringify(
types,
)} but instead got ${JSON.stringify(val && val.type)}`,
)} but instead got ${JSON.stringify(val?.type)}`,
);
}

View File

@ -47,10 +47,7 @@ export default function isNodesEquivalent(a: any, b: any): boolean {
continue;
}
if (
typeof a[field] === "object" &&
(!visitorKeys || !visitorKeys.includes(field))
) {
if (typeof a[field] === "object" && !visitorKeys?.includes(field)) {
for (const key of Object.keys(a[field])) {
if (a[field][key] !== b[field][key]) {
return false;

View File

@ -18,7 +18,7 @@ export function validateField(
val: any,
field: any,
): void {
if (!field || !field.validate) return;
if (!field?.validate) return;
if (field.optional && val == null) return;
field.validate(node, key, val);