Skip to content

Commit

Permalink
add 12 missing NODE_FIELDS (babel#13577)
Browse files Browse the repository at this point in the history
* test: add fields test

* fix(babel-types): add missing NODE_FIELDS and tests

fix babel#13558
fix babel#13563

* chore: avoid using fs-extra

* chore: code cleanup

* chore: avoid util.promisify

* fix: remove bad ts-expect-error suppressions
  • Loading branch information
jedwards1211 authored and nicolo-ribaudo committed Jul 30, 2021
1 parent 01c4d78 commit c97f9c4
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 4 deletions.
2 changes: 0 additions & 2 deletions packages/babel-generator/src/generators/flow.ts
Expand Up @@ -548,12 +548,10 @@ export function OpaqueType(
this.print(node.supertype, node);
}

// @ts-expect-error todo(flow->ts) `.impltype` does not exist on t.DeclareOpaqueType
if (node.impltype) {
this.space();
this.token("=");
this.space();
// @ts-expect-error todo(flow->ts) `.impltype` does not exist on t.DeclareOpaqueType
this.print(node.impltype, node);
}
this.semicolon();
Expand Down
1 change: 0 additions & 1 deletion packages/babel-traverse/src/path/lib/virtual-types.ts
Expand Up @@ -116,7 +116,6 @@ export const Flow = {
} else if (t.isImportDeclaration(node)) {
return node.importKind === "type" || node.importKind === "typeof";
} else if (t.isExportDeclaration(node)) {
// @ts-expect-error todo(flow->ts) `exportKind` does not exist on ExportAllDeclaration
return node.exportKind === "type";
} else if (t.isImportSpecifier(node)) {
return node.importKind === "type" || node.importKind === "typeof";
Expand Down
3 changes: 2 additions & 1 deletion packages/babel-types/package.json
Expand Up @@ -30,7 +30,8 @@
"devDependencies": {
"@babel/generator": "workspace:*",
"@babel/parser": "workspace:*",
"chalk": "^4.1.0"
"chalk": "^4.1.0",
"glob": "^7.1.7"
},
"engines": {
"node": ">=6.9.0"
Expand Down
13 changes: 13 additions & 0 deletions packages/babel-types/src/ast-types/generated/index.ts
Expand Up @@ -643,6 +643,7 @@ export interface RestElement extends BaseNode {
type: "RestElement";
argument: LVal;
decorators?: Array<Decorator> | null;
optional?: boolean | null;
typeAnnotation?: TypeAnnotation | TSTypeAnnotation | Noop | null;
}

Expand All @@ -653,6 +654,7 @@ export interface RestProperty extends BaseNode {
type: "RestProperty";
argument: LVal;
decorators?: Array<Decorator> | null;
optional?: boolean | null;
typeAnnotation?: TypeAnnotation | TSTypeAnnotation | Noop | null;
}

Expand Down Expand Up @@ -751,6 +753,7 @@ export interface ArrayPattern extends BaseNode {
type: "ArrayPattern";
elements: Array<null | PatternLike>;
decorators?: Array<Decorator> | null;
optional?: boolean | null;
typeAnnotation?: TypeAnnotation | TSTypeAnnotation | Noop | null;
}

Expand Down Expand Up @@ -835,6 +838,7 @@ export interface ExportDefaultDeclaration extends BaseNode {
| TSDeclareFunction
| ClassDeclaration
| Expression;
exportKind?: "value" | null;
}

export interface ExportNamedDeclaration extends BaseNode {
Expand Down Expand Up @@ -1024,6 +1028,7 @@ export interface ClassProperty extends BaseNode {
optional?: boolean | null;
override?: boolean;
readonly?: boolean | null;
variance?: Variance | null;
}

export interface ClassPrivateProperty extends BaseNode {
Expand All @@ -1032,7 +1037,10 @@ export interface ClassPrivateProperty extends BaseNode {
value?: Expression | null;
decorators?: Array<Decorator> | null;
static: any;
definite?: boolean | null;
readonly?: boolean | null;
typeAnnotation?: TypeAnnotation | TSTypeAnnotation | Noop | null;
variance?: Variance | null;
}

export interface ClassPrivateMethod extends BaseNode {
Expand Down Expand Up @@ -1142,6 +1150,7 @@ export interface DeclareOpaqueType extends BaseNode {
id: Identifier;
typeParameters?: TypeParameterDeclaration | null;
supertype?: FlowType | null;
impltype?: FlowType | null;
}

export interface DeclareVariable extends BaseNode {
Expand Down Expand Up @@ -1651,6 +1660,8 @@ export interface TSParameterProperty extends BaseNode {
type: "TSParameterProperty";
parameter: Identifier | AssignmentPattern;
accessibility?: "public" | "private" | "protected" | null;
decorators?: Array<Decorator> | null;
override?: boolean | null;
readonly?: boolean | null;
}

Expand Down Expand Up @@ -1710,6 +1721,7 @@ export interface TSPropertySignature extends BaseNode {
typeAnnotation?: TSTypeAnnotation | null;
initializer?: Expression | null;
computed?: boolean | null;
kind: "get" | "set";
optional?: boolean | null;
readonly?: boolean | null;
}
Expand Down Expand Up @@ -1992,6 +2004,7 @@ export interface TSImportEqualsDeclaration extends BaseNode {
type: "TSImportEqualsDeclaration";
id: Identifier;
moduleReference: TSEntityName | TSExternalModuleReference;
importKind?: "type" | "value" | null;
isExport: boolean;
}

Expand Down
26 changes: 26 additions & 0 deletions packages/babel-types/src/definitions/core.ts
Expand Up @@ -900,6 +900,11 @@ defineType("RestElement", {
? assertNodeType("LVal")
: assertNodeType("Identifier", "Pattern", "MemberExpression"),
},
// For Flow
optional: {
validate: assertValueType("boolean"),
optional: true,
},
},
validate(parent, key) {
if (!process.env.BABEL_TYPES_8_BREAKING) return;
Expand Down Expand Up @@ -1206,6 +1211,10 @@ defineType("ArrayPattern", {
),
optional: true,
},
optional: {
validate: assertValueType("boolean"),
optional: true,
},
},
});

Expand Down Expand Up @@ -1440,6 +1449,7 @@ defineType("ExportDefaultDeclaration", {
"Expression",
),
},
exportKind: validateOptional(assertOneOf("value")),
},
});

Expand Down Expand Up @@ -2095,6 +2105,10 @@ defineType("ClassProperty", {
validate: assertValueType("boolean"),
optional: true,
},
variance: {
validate: assertNodeType("Variance"),
optional: true,
},
},
});

Expand Down Expand Up @@ -2123,6 +2137,18 @@ defineType("ClassPrivateProperty", {
),
optional: true,
},
readonly: {
validate: assertValueType("boolean"),
optional: true,
},
definite: {
validate: assertValueType("boolean"),
optional: true,
},
variance: {
validate: assertNodeType("Variance"),
optional: true,
},
},
});

Expand Down
1 change: 1 addition & 0 deletions packages/babel-types/src/definitions/flow.ts
Expand Up @@ -121,6 +121,7 @@ defineType("DeclareOpaqueType", {
id: validateType("Identifier"),
typeParameters: validateOptionalType("TypeParameterDeclaration"),
supertype: validateOptionalType("FlowType"),
impltype: validateOptionalType("FlowType"),
},
});

Expand Down
18 changes: 18 additions & 0 deletions packages/babel-types/src/definitions/typescript.ts
Expand Up @@ -49,6 +49,17 @@ defineType("TSParameterProperty", {
parameter: {
validate: assertNodeType("Identifier", "AssignmentPattern"),
},
override: {
validate: assertValueType("boolean"),
optional: true,
},
decorators: {
validate: chain(
assertValueType("array"),
assertEach(assertNodeType("Decorator")),
),
optional: true,
},
},
});

Expand Down Expand Up @@ -110,6 +121,9 @@ defineType("TSPropertySignature", {
readonly: validateOptional(bool),
typeAnnotation: validateOptionalType("TSTypeAnnotation"),
initializer: validateOptionalType("Expression"),
kind: {
validate: assertOneOf("get", "set"),
},
},
});

Expand Down Expand Up @@ -494,6 +508,10 @@ defineType("TSImportEqualsDeclaration", {
"TSEntityName",
"TSExternalModuleReference",
]),
importKind: {
validate: assertOneOf("type", "value"),
optional: true,
},
},
});

Expand Down
116 changes: 116 additions & 0 deletions packages/babel-types/test/fields.js
@@ -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)}`,
);
}
}),
);
});
1 change: 1 addition & 0 deletions yarn.lock
Expand Up @@ -3606,6 +3606,7 @@ __metadata:
"@babel/helper-validator-identifier": "workspace:^7.14.8"
"@babel/parser": "workspace:*"
chalk: ^4.1.0
glob: ^7.1.7
to-fast-properties: ^2.0.0
languageName: unknown
linkType: soft
Expand Down

0 comments on commit c97f9c4

Please sign in to comment.