add 12 missing NODE_FIELDS (#13577)
* test: add fields test * fix(babel-types): add missing NODE_FIELDS and tests fix #13558 fix #13563 * chore: avoid using fs-extra * chore: code cleanup * chore: avoid util.promisify * fix: remove bad ts-expect-error suppressions
This commit is contained in:
parent
844baebd26
commit
1d48bb0d8c
@ -548,12 +548,10 @@ export function OpaqueType(
|
|||||||
this.print(node.supertype, node);
|
this.print(node.supertype, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @ts-expect-error todo(flow->ts) `.impltype` does not exist on t.DeclareOpaqueType
|
|
||||||
if (node.impltype) {
|
if (node.impltype) {
|
||||||
this.space();
|
this.space();
|
||||||
this.token("=");
|
this.token("=");
|
||||||
this.space();
|
this.space();
|
||||||
// @ts-expect-error todo(flow->ts) `.impltype` does not exist on t.DeclareOpaqueType
|
|
||||||
this.print(node.impltype, node);
|
this.print(node.impltype, node);
|
||||||
}
|
}
|
||||||
this.semicolon();
|
this.semicolon();
|
||||||
|
|||||||
@ -116,7 +116,6 @@ export const Flow = {
|
|||||||
} else if (t.isImportDeclaration(node)) {
|
} else if (t.isImportDeclaration(node)) {
|
||||||
return node.importKind === "type" || node.importKind === "typeof";
|
return node.importKind === "type" || node.importKind === "typeof";
|
||||||
} else if (t.isExportDeclaration(node)) {
|
} else if (t.isExportDeclaration(node)) {
|
||||||
// @ts-expect-error todo(flow->ts) `exportKind` does not exist on ExportAllDeclaration
|
|
||||||
return node.exportKind === "type";
|
return node.exportKind === "type";
|
||||||
} else if (t.isImportSpecifier(node)) {
|
} else if (t.isImportSpecifier(node)) {
|
||||||
return node.importKind === "type" || node.importKind === "typeof";
|
return node.importKind === "type" || node.importKind === "typeof";
|
||||||
|
|||||||
@ -30,7 +30,8 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/generator": "workspace:*",
|
"@babel/generator": "workspace:*",
|
||||||
"@babel/parser": "workspace:*",
|
"@babel/parser": "workspace:*",
|
||||||
"chalk": "^4.1.0"
|
"chalk": "^4.1.0",
|
||||||
|
"glob": "^7.1.7"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
|
|||||||
@ -643,6 +643,7 @@ export interface RestElement extends BaseNode {
|
|||||||
type: "RestElement";
|
type: "RestElement";
|
||||||
argument: LVal;
|
argument: LVal;
|
||||||
decorators?: Array<Decorator> | null;
|
decorators?: Array<Decorator> | null;
|
||||||
|
optional?: boolean | null;
|
||||||
typeAnnotation?: TypeAnnotation | TSTypeAnnotation | Noop | null;
|
typeAnnotation?: TypeAnnotation | TSTypeAnnotation | Noop | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,6 +654,7 @@ export interface RestProperty extends BaseNode {
|
|||||||
type: "RestProperty";
|
type: "RestProperty";
|
||||||
argument: LVal;
|
argument: LVal;
|
||||||
decorators?: Array<Decorator> | null;
|
decorators?: Array<Decorator> | null;
|
||||||
|
optional?: boolean | null;
|
||||||
typeAnnotation?: TypeAnnotation | TSTypeAnnotation | Noop | null;
|
typeAnnotation?: TypeAnnotation | TSTypeAnnotation | Noop | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -751,6 +753,7 @@ export interface ArrayPattern extends BaseNode {
|
|||||||
type: "ArrayPattern";
|
type: "ArrayPattern";
|
||||||
elements: Array<null | PatternLike>;
|
elements: Array<null | PatternLike>;
|
||||||
decorators?: Array<Decorator> | null;
|
decorators?: Array<Decorator> | null;
|
||||||
|
optional?: boolean | null;
|
||||||
typeAnnotation?: TypeAnnotation | TSTypeAnnotation | Noop | null;
|
typeAnnotation?: TypeAnnotation | TSTypeAnnotation | Noop | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -835,6 +838,7 @@ export interface ExportDefaultDeclaration extends BaseNode {
|
|||||||
| TSDeclareFunction
|
| TSDeclareFunction
|
||||||
| ClassDeclaration
|
| ClassDeclaration
|
||||||
| Expression;
|
| Expression;
|
||||||
|
exportKind?: "value" | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ExportNamedDeclaration extends BaseNode {
|
export interface ExportNamedDeclaration extends BaseNode {
|
||||||
@ -1024,6 +1028,7 @@ export interface ClassProperty extends BaseNode {
|
|||||||
optional?: boolean | null;
|
optional?: boolean | null;
|
||||||
override?: boolean;
|
override?: boolean;
|
||||||
readonly?: boolean | null;
|
readonly?: boolean | null;
|
||||||
|
variance?: Variance | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ClassPrivateProperty extends BaseNode {
|
export interface ClassPrivateProperty extends BaseNode {
|
||||||
@ -1032,7 +1037,10 @@ export interface ClassPrivateProperty extends BaseNode {
|
|||||||
value?: Expression | null;
|
value?: Expression | null;
|
||||||
decorators?: Array<Decorator> | null;
|
decorators?: Array<Decorator> | null;
|
||||||
static: any;
|
static: any;
|
||||||
|
definite?: boolean | null;
|
||||||
|
readonly?: boolean | null;
|
||||||
typeAnnotation?: TypeAnnotation | TSTypeAnnotation | Noop | null;
|
typeAnnotation?: TypeAnnotation | TSTypeAnnotation | Noop | null;
|
||||||
|
variance?: Variance | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ClassPrivateMethod extends BaseNode {
|
export interface ClassPrivateMethod extends BaseNode {
|
||||||
@ -1142,6 +1150,7 @@ export interface DeclareOpaqueType extends BaseNode {
|
|||||||
id: Identifier;
|
id: Identifier;
|
||||||
typeParameters?: TypeParameterDeclaration | null;
|
typeParameters?: TypeParameterDeclaration | null;
|
||||||
supertype?: FlowType | null;
|
supertype?: FlowType | null;
|
||||||
|
impltype?: FlowType | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DeclareVariable extends BaseNode {
|
export interface DeclareVariable extends BaseNode {
|
||||||
@ -1651,6 +1660,8 @@ export interface TSParameterProperty extends BaseNode {
|
|||||||
type: "TSParameterProperty";
|
type: "TSParameterProperty";
|
||||||
parameter: Identifier | AssignmentPattern;
|
parameter: Identifier | AssignmentPattern;
|
||||||
accessibility?: "public" | "private" | "protected" | null;
|
accessibility?: "public" | "private" | "protected" | null;
|
||||||
|
decorators?: Array<Decorator> | null;
|
||||||
|
override?: boolean | null;
|
||||||
readonly?: boolean | null;
|
readonly?: boolean | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1710,6 +1721,7 @@ export interface TSPropertySignature extends BaseNode {
|
|||||||
typeAnnotation?: TSTypeAnnotation | null;
|
typeAnnotation?: TSTypeAnnotation | null;
|
||||||
initializer?: Expression | null;
|
initializer?: Expression | null;
|
||||||
computed?: boolean | null;
|
computed?: boolean | null;
|
||||||
|
kind: "get" | "set";
|
||||||
optional?: boolean | null;
|
optional?: boolean | null;
|
||||||
readonly?: boolean | null;
|
readonly?: boolean | null;
|
||||||
}
|
}
|
||||||
@ -1992,6 +2004,7 @@ export interface TSImportEqualsDeclaration extends BaseNode {
|
|||||||
type: "TSImportEqualsDeclaration";
|
type: "TSImportEqualsDeclaration";
|
||||||
id: Identifier;
|
id: Identifier;
|
||||||
moduleReference: TSEntityName | TSExternalModuleReference;
|
moduleReference: TSEntityName | TSExternalModuleReference;
|
||||||
|
importKind?: "type" | "value" | null;
|
||||||
isExport: boolean;
|
isExport: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -900,6 +900,11 @@ defineType("RestElement", {
|
|||||||
? assertNodeType("LVal")
|
? assertNodeType("LVal")
|
||||||
: assertNodeType("Identifier", "Pattern", "MemberExpression"),
|
: assertNodeType("Identifier", "Pattern", "MemberExpression"),
|
||||||
},
|
},
|
||||||
|
// For Flow
|
||||||
|
optional: {
|
||||||
|
validate: assertValueType("boolean"),
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
validate(parent, key) {
|
validate(parent, key) {
|
||||||
if (!process.env.BABEL_TYPES_8_BREAKING) return;
|
if (!process.env.BABEL_TYPES_8_BREAKING) return;
|
||||||
@ -1206,6 +1211,10 @@ defineType("ArrayPattern", {
|
|||||||
),
|
),
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
|
optional: {
|
||||||
|
validate: assertValueType("boolean"),
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1440,6 +1449,7 @@ defineType("ExportDefaultDeclaration", {
|
|||||||
"Expression",
|
"Expression",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
exportKind: validateOptional(assertOneOf("value")),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2095,6 +2105,10 @@ defineType("ClassProperty", {
|
|||||||
validate: assertValueType("boolean"),
|
validate: assertValueType("boolean"),
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
|
variance: {
|
||||||
|
validate: assertNodeType("Variance"),
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2123,6 +2137,18 @@ defineType("ClassPrivateProperty", {
|
|||||||
),
|
),
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
|
readonly: {
|
||||||
|
validate: assertValueType("boolean"),
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
definite: {
|
||||||
|
validate: assertValueType("boolean"),
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
variance: {
|
||||||
|
validate: assertNodeType("Variance"),
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -121,6 +121,7 @@ defineType("DeclareOpaqueType", {
|
|||||||
id: validateType("Identifier"),
|
id: validateType("Identifier"),
|
||||||
typeParameters: validateOptionalType("TypeParameterDeclaration"),
|
typeParameters: validateOptionalType("TypeParameterDeclaration"),
|
||||||
supertype: validateOptionalType("FlowType"),
|
supertype: validateOptionalType("FlowType"),
|
||||||
|
impltype: validateOptionalType("FlowType"),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -49,6 +49,17 @@ defineType("TSParameterProperty", {
|
|||||||
parameter: {
|
parameter: {
|
||||||
validate: assertNodeType("Identifier", "AssignmentPattern"),
|
validate: assertNodeType("Identifier", "AssignmentPattern"),
|
||||||
},
|
},
|
||||||
|
override: {
|
||||||
|
validate: assertValueType("boolean"),
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
decorators: {
|
||||||
|
validate: chain(
|
||||||
|
assertValueType("array"),
|
||||||
|
assertEach(assertNodeType("Decorator")),
|
||||||
|
),
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -110,6 +121,9 @@ defineType("TSPropertySignature", {
|
|||||||
readonly: validateOptional(bool),
|
readonly: validateOptional(bool),
|
||||||
typeAnnotation: validateOptionalType("TSTypeAnnotation"),
|
typeAnnotation: validateOptionalType("TSTypeAnnotation"),
|
||||||
initializer: validateOptionalType("Expression"),
|
initializer: validateOptionalType("Expression"),
|
||||||
|
kind: {
|
||||||
|
validate: assertOneOf("get", "set"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -494,6 +508,10 @@ defineType("TSImportEqualsDeclaration", {
|
|||||||
"TSEntityName",
|
"TSEntityName",
|
||||||
"TSExternalModuleReference",
|
"TSExternalModuleReference",
|
||||||
]),
|
]),
|
||||||
|
importKind: {
|
||||||
|
validate: assertOneOf("type", "value"),
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
116
packages/babel-types/test/fields.js
Normal file
116
packages/babel-types/test/fields.js
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
import * as t from "../lib";
|
||||||
|
import glob from "glob";
|
||||||
|
import path from "path";
|
||||||
|
import fs from "fs";
|
||||||
|
import { inspect } from "util";
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-restricted-globals
|
||||||
|
const packages = path.resolve(__dirname, "..", "..");
|
||||||
|
|
||||||
|
function readJson(file) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
fs.readFile(file, "utf8", (err, data) => {
|
||||||
|
if (err) reject(err);
|
||||||
|
else resolve(JSON.parse(data));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function traverse(thing, visitor) {
|
||||||
|
if (Array.isArray(thing)) {
|
||||||
|
thing.forEach(elem => traverse(elem, visitor));
|
||||||
|
} else if (thing instanceof Object && typeof thing.type === "string") {
|
||||||
|
visitor(thing);
|
||||||
|
for (const key in thing) {
|
||||||
|
const value = thing[key];
|
||||||
|
if (value instanceof Object) traverse(value, visitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const files = glob.sync(
|
||||||
|
path.join("babel-parser", "test", "**", "output.json"),
|
||||||
|
{
|
||||||
|
cwd: packages,
|
||||||
|
ignore: [
|
||||||
|
path.join("**", "estree*", "**"),
|
||||||
|
path.join("**", "is-expression-babel-parser", "**"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const ignoredFields = {
|
||||||
|
ArrowFunctionExpression: { id: true, predicate: true },
|
||||||
|
ClassMethod: { id: true, predicate: true },
|
||||||
|
ClassPrivateMethod: { id: true, predicate: true },
|
||||||
|
ClassPrivateProperty: { declare: true, optional: true },
|
||||||
|
FunctionDeclaration: { predicate: true },
|
||||||
|
FunctionExpression: { predicate: true },
|
||||||
|
ImportDeclaration: { attributes: true },
|
||||||
|
ObjectProperty: { method: true },
|
||||||
|
ObjectMethod: { method: true, id: true, predicate: true },
|
||||||
|
StaticBlock: { static: true },
|
||||||
|
TSDeclareMethod: { id: true },
|
||||||
|
};
|
||||||
|
|
||||||
|
function isEmpty(obj) {
|
||||||
|
for (const key in obj) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("NODE_FIELDS contains all fields in", function () {
|
||||||
|
files.forEach(file =>
|
||||||
|
it(`${file}`, async function () {
|
||||||
|
const ast = await readJson(path.resolve(packages, file));
|
||||||
|
if (ast.type === "File" && ast.errors && ast.errors.length) return;
|
||||||
|
t[`assert${ast.type}`](ast);
|
||||||
|
const missingFields = {};
|
||||||
|
traverse(ast, node => {
|
||||||
|
const { type } = node;
|
||||||
|
switch (type) {
|
||||||
|
case "File":
|
||||||
|
case "CommentBlock":
|
||||||
|
case "CommentLine":
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ignoredFields[type] === true) return;
|
||||||
|
const fields = t.NODE_FIELDS[type];
|
||||||
|
if (!fields) {
|
||||||
|
if (!missingFields[type]) {
|
||||||
|
missingFields[type] = {
|
||||||
|
MISSING_TYPE: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (const field in node) {
|
||||||
|
switch (field) {
|
||||||
|
case "type":
|
||||||
|
case "start":
|
||||||
|
case "end":
|
||||||
|
case "loc":
|
||||||
|
case "range":
|
||||||
|
case "leadingComments":
|
||||||
|
case "innerComments":
|
||||||
|
case "trailingComments":
|
||||||
|
case "comments":
|
||||||
|
case "extra":
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!fields[field]) {
|
||||||
|
if (ignoredFields[type] && ignoredFields[type][field]) continue;
|
||||||
|
if (!missingFields[type]) missingFields[type] = {};
|
||||||
|
if (!missingFields[type][field]) {
|
||||||
|
missingFields[type][field] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!isEmpty(missingFields)) {
|
||||||
|
throw new Error(
|
||||||
|
`the following NODE_FIELDS were missing: ${inspect(missingFields)}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
@ -3606,6 +3606,7 @@ __metadata:
|
|||||||
"@babel/helper-validator-identifier": "workspace:^7.14.8"
|
"@babel/helper-validator-identifier": "workspace:^7.14.8"
|
||||||
"@babel/parser": "workspace:*"
|
"@babel/parser": "workspace:*"
|
||||||
chalk: ^4.1.0
|
chalk: ^4.1.0
|
||||||
|
glob: ^7.1.7
|
||||||
to-fast-properties: ^2.0.0
|
to-fast-properties: ^2.0.0
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user