Add stricter Optional Chain node validation (#11250)
* Add stricter Optional Chain node validation Optional chains cannot start with `optional: false`. Somewhere in the `object`/`callee` tree, there must be an optional with `optional: true`. * Print current node's type when finding an error.
This commit is contained in:
parent
59976680df
commit
56500603da
@ -1,5 +1,6 @@
|
||||
// @flow
|
||||
import defineType, {
|
||||
assertOptionalChainStart,
|
||||
assertEach,
|
||||
assertNodeType,
|
||||
assertNodeOrValueType,
|
||||
@ -105,7 +106,9 @@ defineType("OptionalMemberExpression", {
|
||||
default: false,
|
||||
},
|
||||
optional: {
|
||||
validate: assertValueType("boolean"),
|
||||
validate: !process.env.BABEL_TYPES_8_BREAKING
|
||||
? assertValueType("boolean")
|
||||
: chain(assertValueType("boolean"), assertOptionalChainStart()),
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -151,7 +154,9 @@ defineType("OptionalCallExpression", {
|
||||
),
|
||||
},
|
||||
optional: {
|
||||
validate: assertValueType("boolean"),
|
||||
validate: !process.env.BABEL_TYPES_8_BREAKING
|
||||
? assertValueType("boolean")
|
||||
: chain(assertValueType("boolean"), assertOptionalChainStart()),
|
||||
},
|
||||
typeArguments: {
|
||||
validate: assertNodeType("TypeParameterInstantiation"),
|
||||
|
||||
@ -186,6 +186,34 @@ export function assertShape(shape: { [string]: FieldOptions }): Validator {
|
||||
return validate;
|
||||
}
|
||||
|
||||
export function assertOptionalChainStart(): Validator {
|
||||
function validate(node) {
|
||||
let current = node;
|
||||
while (node) {
|
||||
const { type } = current;
|
||||
if (type === "OptionalCallExpression") {
|
||||
if (current.optional) return;
|
||||
current = current.callee;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (type === "OptionalMemberExpression") {
|
||||
if (current.optional) return;
|
||||
current = current.object;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
throw new TypeError(
|
||||
`Non-optional ${node.type} must chain from an optional OptionalMemberExpression or OptionalCallExpression. Found chain from ${current?.type}`,
|
||||
);
|
||||
}
|
||||
|
||||
return validate;
|
||||
}
|
||||
|
||||
export function chain(...fns: Array<Validator>): Validator {
|
||||
function validate(...args) {
|
||||
for (const fn of fns) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user