Forbid pass non-node object to print() (#13293)
This commit is contained in:
1 parent
75025561c4
commit
a166544583
4 files changed
+67
-14
No files matched your search
@@ -112,8 +112,11 @@ function printTypeParameter(path, options, print) {
|
||||
const node = path.getValue();
|
||||
const parts = [];
|
||||
const parent = path.getParentNode();
|
||||
|
||||
const name = node.type === "TSTypeParameter" ? print("name") : node.name;
|
||||
|
||||
if (parent.type === "TSMappedType") {
|
||||
parts.push("[", print("name"));
|
||||
parts.push("[", name);
|
||||
if (node.constraint) {
|
||||
parts.push(" in ", print("constraint"));
|
||||
}
|
||||
@@ -139,7 +142,7 @@ function printTypeParameter(path, options, print) {
|
||||
parts.push("out ");
|
||||
}
|
||||
|
||||
parts.push(print("name"));
|
||||
parts.push(name);
|
||||
|
||||
if (node.bound) {
|
||||
parts.push(": ", print("bound"));
|
||||
|
||||
@@ -89,12 +89,21 @@ import { printLiteral } from "./print/literal.js";
|
||||
import { printDecorators } from "./print/decorators.js";
|
||||
|
||||
function genericPrint(path, options, print, args) {
|
||||
const node = path.getValue();
|
||||
|
||||
if (node === undefined || node === null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
ensurePrintingNode(path);
|
||||
}
|
||||
|
||||
const printed = printPathNoParens(path, options, print, args);
|
||||
if (!printed) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const node = path.getValue();
|
||||
const { type } = node;
|
||||
// Their decorators are handled themselves, and they can't have parentheses
|
||||
if (
|
||||
@@ -170,14 +179,6 @@ function printPathNoParens(path, options, print, args) {
|
||||
const node = path.getValue();
|
||||
const semi = options.semi ? ";" : "";
|
||||
|
||||
if (!node) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (typeof node === "string") {
|
||||
return node;
|
||||
}
|
||||
|
||||
for (const printer of [
|
||||
printLiteral,
|
||||
printHtmlBinding,
|
||||
@@ -778,7 +779,7 @@ function printPathNoParens(path, options, print, args) {
|
||||
case "TaggedTemplateExpression":
|
||||
return [print("tag"), print("typeParameters"), print("quasi")];
|
||||
case "PrivateIdentifier":
|
||||
return ["#", print("name")];
|
||||
return ["#", node.name];
|
||||
case "PrivateName":
|
||||
return ["#", print("id")];
|
||||
|
||||
@@ -846,6 +847,46 @@ function canAttachComment(node) {
|
||||
);
|
||||
}
|
||||
|
||||
function ensurePrintingNode(path) {
|
||||
let name = path.getName();
|
||||
|
||||
// AST root
|
||||
if (name === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof name === "number") {
|
||||
/*
|
||||
Nodes in array are stored in path.stack like
|
||||
|
||||
```js
|
||||
[
|
||||
parentNode,
|
||||
property, // <-
|
||||
array,
|
||||
index,
|
||||
node,
|
||||
]
|
||||
```
|
||||
*/
|
||||
name = path.stack[path.stack.length - 4];
|
||||
}
|
||||
|
||||
const parent = path.getParentNode();
|
||||
const visitorKeys = getVisitorKeys(parent);
|
||||
if (visitorKeys.includes(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
throw Object.assign(new Error("Calling `print()` on non-node object."), {
|
||||
parentNode: parent,
|
||||
allowedProperties: visitorKeys,
|
||||
printingProperty: name,
|
||||
printingValue: path.getValue(),
|
||||
});
|
||||
}
|
||||
|
||||
const printer = {
|
||||
preprocess,
|
||||
print: genericPrint,
|
||||
|
||||
@@ -10,7 +10,7 @@ const angularVisitorKeys = {
|
||||
NGQuotedExpression: [],
|
||||
NGMicrosyntax: ["body"],
|
||||
NGMicrosyntaxKey: [],
|
||||
NGMicrosyntaxExpression: ["expression", "name"],
|
||||
NGMicrosyntaxExpression: ["expression", "alias"],
|
||||
NGMicrosyntaxKeyedExpression: ["key", "expression"],
|
||||
NGMicrosyntaxLet: ["key", "value"],
|
||||
NGMicrosyntaxAs: ["key", "alias"],
|
||||
@@ -46,6 +46,11 @@ const additionalVisitorKeys = {
|
||||
ArrowFunctionExpression: ["predicate"],
|
||||
DeclareFunction: ["predicate"],
|
||||
FunctionDeclaration: ["predicate"],
|
||||
ClassProperty: ["variance"],
|
||||
ClassPrivateProperty: ["variance"],
|
||||
EnumBooleanMember: ["init"],
|
||||
|
||||
Property: ["decorators"],
|
||||
};
|
||||
|
||||
export default unionVisitorKeys([
|
||||
|
||||
@@ -123,12 +123,14 @@ exports[`visitor keys estree 1`] = `
|
||||
"value",
|
||||
"decorators",
|
||||
"typeAnnotation",
|
||||
"variance",
|
||||
],
|
||||
"ClassProperty": [
|
||||
"key",
|
||||
"value",
|
||||
"typeAnnotation",
|
||||
"decorators",
|
||||
"variance",
|
||||
],
|
||||
"ConditionalExpression": [
|
||||
"test",
|
||||
@@ -212,6 +214,7 @@ exports[`visitor keys estree 1`] = `
|
||||
],
|
||||
"EnumBooleanMember": [
|
||||
"id",
|
||||
"init",
|
||||
],
|
||||
"EnumDeclaration": [
|
||||
"id",
|
||||
@@ -468,7 +471,7 @@ exports[`visitor keys estree 1`] = `
|
||||
],
|
||||
"NGMicrosyntaxExpression": [
|
||||
"expression",
|
||||
"name",
|
||||
"alias",
|
||||
],
|
||||
"NGMicrosyntaxKey": [],
|
||||
"NGMicrosyntaxKeyedExpression": [
|
||||
@@ -597,6 +600,7 @@ exports[`visitor keys estree 1`] = `
|
||||
"Property": [
|
||||
"key",
|
||||
"value",
|
||||
"decorators",
|
||||
],
|
||||
"PropertyDefinition": [
|
||||
"decorators",
|
||||
|
||||
Reference in new issue
Block a user