From 48071f4e15da04759e5653b0774376862011ee24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Wed, 14 Apr 2021 16:31:53 -0400 Subject: [PATCH 1/6] add alias docs generator --- .../babel-types/scripts/generators/docs.js | 120 +++++++++++++++++- 1 file changed, 118 insertions(+), 2 deletions(-) diff --git a/packages/babel-types/scripts/generators/docs.js b/packages/babel-types/scripts/generators/docs.js index 07a44bbd3754..143ed3a3c283 100644 --- a/packages/babel-types/scripts/generators/docs.js +++ b/packages/babel-types/scripts/generators/docs.js @@ -130,11 +130,12 @@ function printAliasKeys(key, readme) { ); } } - +readme.push("### Node Builders"); +readme.push(""); Object.keys(t.BUILDER_KEYS) .sort() .forEach(function (key) { - readme.push("### " + toFunctionName(key)); + readme.push("#### " + toFunctionName(key)); readme.push(""); readme.push("```javascript"); readme.push( @@ -159,4 +160,119 @@ Object.keys(t.BUILDER_KEYS) readme.push(""); }); +function generateMapAliasToNodeTypes() { + const result = new Map(); + for (const nodeType of Object.keys(t.ALIAS_KEYS)) { + const aliases = t.ALIAS_KEYS[nodeType]; + if (!aliases) continue; + for (const alias of aliases) { + if (!result.has(alias)) { + result.set(alias, []); + } + const nodeTypes = result.get(alias); + nodeTypes.push(nodeType); + } + } + return result; +} +const aliasDescriptions = { + Binary: + "A cover of BinaryExpression and LogicalExpression, which share the same AST shape.", + Block: "A cover of BlockStatement and its alike.", + BlockParent: + "A cover of AST nodes that start an execution context with new [LexicalEnvironment](https://tc39.es/ecma262/#table-additional-state-components-for-ecmascript-code-execution-contexts). In other words, they define the scope of `let` and `const` declarations.", + Class: + "A cover of ClassExpression and ClassDeclaration, which share the same AST shape.", + CompletionStatement: + "A statement that indicates the [completion records](https://tc39.es/ecma262/#sec-completion-record-specification-type). In other words, they define the control flow of the program, such as when should a loop break or an action throws critical errors.", + Conditional: + "A cover of ConditionalExpression and IfStatement, which share the same AST shape.", + Declaration: + "A cover of any [Declaration](https://tc39.es/ecma262/#prod-Declaration)s.", + EnumBody: + "A cover of enum bodies defined in [TypeScript](https://www.typescriptlang.org/docs/handbook/enums.html) and Flow.", + EnumMember: + "A cover of enum membors defined in [TypeScript](https://www.typescriptlang.org/docs/handbook/enums.html) and Flow.", + ExportDeclaration: + "A cover of any [ExportDeclaration](https://tc39.es/ecma262/#prod-ExportDeclaration)s.", + Expression: + "A cover of any [Expression](https://tc39.es/ecma262/#sec-ecmascript-language-expressions)s.", + ExpressionWrapper: + "A wrapper of expression that does not have run semantics.", + Flow: "A cover of AST nodes defined for Flow.", + FlowBaseAnnotation: "A cover of primary Flow type annotations.", + FlowDeclaration: "A cover of Flow declarations.", + FlowPredicate: "A cover of Flow predicates.", + FlowType: "A cover of Flow type annotations.", + For: + "A cover of [ForStatement](https://tc39.es/ecma262/#sec-for-statement)s and [ForXStatement](#forxstatement)s.", + ForXStatement: + "A cover of [ForInStatements and ForOfStatements](https://tc39.es/ecma262/#sec-for-in-and-for-of-statements).", + Function: + "A cover of functions and [method](#method)s, the must have `body` and `params`. Note: `Function` is different to `FunctionParent`.", + FunctionParent: + "A cover of AST nodes that start an execution context with new [VariableEnvironment](https://tc39.es/ecma262/#table-additional-state-components-for-ecmascript-code-execution-contexts). In other words, they define the scope of `var` declarations. FunctionParent did not include `Program` since Babel 7.", + Immutable: "A cover of immutable AST nodes.", + JSX: + "A cover of AST nodes defined for [JSX](https://facebook.github.io/jsx/).", + LVal: + "A cover of [BindingPattern](https://tc39.es/ecma262/#prod-BindingPattern)s. ", + Literal: + "A cover of [Literal](https://tc39.es/ecma262/#sec-primary-expression-literals)s, [Regular Expression Literal](https://tc39.es/ecma262/#sec-primary-expression-regular-expression-literals)s and [Template Literal](https://tc39.es/ecma262/#sec-template-literals)s.", + Loop: "A cover of loop statements.", + Method: "A cover of object methods and class methods.", + ModuleDeclaration: + "A cover of ImportDeclaration and [ExportDeclaration](#exportdeclaration)", + ModuleSpecifier: + "A cover of import and export specifiers. Note: It is _not_ the [ModuleSpecifier](https://tc39.es/ecma262/#prod-ModuleSpecifier) defined in the spec.", + ObjectMember: + "A cover of [members](https://tc39.es/ecma262/#prod-PropertyDefinitionList) in an object literal.", + Pattern: "A cover of BindingPattern except Identifiers.", + PatternLike: "= LVal?", + Private: "A cover of private class elements and private identifiers.", + Property: "A cover of object properties and class properties.", + Pureish: + "A cover of AST nodes which does not have side-effect. In other words, there is no observable behaviour changes if they are evaluated more than once.", + Scopable: + "A cover of [FunctionParent](#FunctionParent) and [BlockParent](#BlockParent).", + Statement: + "A cover of any [Statement](https://tc39.es/ecma262/#prod-Statement)s.", + TSBaseType: "A cover of primary TypeScript type annotations.", + TSEntityName: "A cover of ts entities.", + TSType: "A cover of TypeScript type annotations.", + TSTypeElement: "A cover of TypeScript type declarations.", + Terminatorless: + "A cover of AST nodes whose semantic will change when a line terminator is inserted between the operator and the operand.", + UnaryLike: "A cover of UnaryExpression and SpreadElement.", + UserWhitespacable: "", + While: + "A cover of DoWhileStatement and WhileStatement, which share the same AST shape.", +}; +const mapAliasToNodeTypes = generateMapAliasToNodeTypes(); +readme.push("### Aliases"); +readme.push(""); +for (const alias of [...mapAliasToNodeTypes.keys()].sort()) { + const nodeTypes = mapAliasToNodeTypes.get(alias); + if (!(alias in aliasDescriptions)) { + throw new Error( + 'Missing alias descriptions of "' + + alias + + ", which covers " + + nodeTypes.join(",") + ); + } + readme.push("#### " + alias); + readme.push(""); + readme.push(aliasDescriptions[alias]); + readme.push("```javascript"); + readme.push("t.is" + alias + "(node);"); + readme.push("```"); + readme.push(""); + readme.push("Covered nodes: "); + for (const nodeType of nodeTypes) { + readme.push("- `" + nodeType + "`"); + } + readme.push(""); +} + process.stdout.write(readme.join("\n")); From 4fbcc4bfb5ed5809f047b5bcfd58fc5eaa04001a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Wed, 14 Apr 2021 12:01:40 -0400 Subject: [PATCH 2/6] fix LVal and PatternLike --- packages/babel-types/scripts/generators/docs.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/babel-types/scripts/generators/docs.js b/packages/babel-types/scripts/generators/docs.js index 143ed3a3c283..acdadaedb320 100644 --- a/packages/babel-types/scripts/generators/docs.js +++ b/packages/babel-types/scripts/generators/docs.js @@ -216,7 +216,7 @@ const aliasDescriptions = { JSX: "A cover of AST nodes defined for [JSX](https://facebook.github.io/jsx/).", LVal: - "A cover of [BindingPattern](https://tc39.es/ecma262/#prod-BindingPattern)s. ", + "A cover of left hand side expressions used in the `left` of assignment expressions and [ForXStatement](#forxstatement)s. ", Literal: "A cover of [Literal](https://tc39.es/ecma262/#sec-primary-expression-literals)s, [Regular Expression Literal](https://tc39.es/ecma262/#sec-primary-expression-regular-expression-literals)s and [Template Literal](https://tc39.es/ecma262/#sec-template-literals)s.", Loop: "A cover of loop statements.", @@ -227,8 +227,10 @@ const aliasDescriptions = { "A cover of import and export specifiers. Note: It is _not_ the [ModuleSpecifier](https://tc39.es/ecma262/#prod-ModuleSpecifier) defined in the spec.", ObjectMember: "A cover of [members](https://tc39.es/ecma262/#prod-PropertyDefinitionList) in an object literal.", - Pattern: "A cover of BindingPattern except Identifiers.", - PatternLike: "= LVal?", + Pattern: + "A cover of [BindingPattern](https://tc39.es/ecma262/#prod-BindingPattern) except Identifiers.", + PatternLike: + "A cover of [BindingPattern](https://tc39.es/ecma262/#prod-BindingPattern)s. ", Private: "A cover of private class elements and private identifiers.", Property: "A cover of object properties and class properties.", Pureish: From 67edf8f569fe67c56c2d67127f8184a626d21b8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Wed, 14 Apr 2021 12:11:13 -0400 Subject: [PATCH 3/6] sort alias covered node types --- packages/babel-types/scripts/generators/docs.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/babel-types/scripts/generators/docs.js b/packages/babel-types/scripts/generators/docs.js index acdadaedb320..9cbaea13b983 100644 --- a/packages/babel-types/scripts/generators/docs.js +++ b/packages/babel-types/scripts/generators/docs.js @@ -255,6 +255,7 @@ readme.push("### Aliases"); readme.push(""); for (const alias of [...mapAliasToNodeTypes.keys()].sort()) { const nodeTypes = mapAliasToNodeTypes.get(alias); + nodeTypes.sort(); if (!(alias in aliasDescriptions)) { throw new Error( 'Missing alias descriptions of "' + From bd0c7ca3fdae7a7d22b3e06546d59e63018cd4b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Wed, 14 Apr 2021 12:17:03 -0400 Subject: [PATCH 4/6] add inner links between alias and node types --- packages/babel-types/scripts/generators/docs.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/babel-types/scripts/generators/docs.js b/packages/babel-types/scripts/generators/docs.js index 9cbaea13b983..d081d5036eca 100644 --- a/packages/babel-types/scripts/generators/docs.js +++ b/packages/babel-types/scripts/generators/docs.js @@ -124,7 +124,7 @@ function printAliasKeys(key, readme) { "Aliases: " + t.ALIAS_KEYS[key] .map(function (key) { - return "`" + key + "`"; + return "[`" + key + "`](#" + key.toLowerCase() + ")"; }) .join(", ") ); @@ -273,7 +273,7 @@ for (const alias of [...mapAliasToNodeTypes.keys()].sort()) { readme.push(""); readme.push("Covered nodes: "); for (const nodeType of nodeTypes) { - readme.push("- `" + nodeType + "`"); + readme.push("- [`" + nodeType + "`](#" + nodeType.toLowerCase() + ")"); } readme.push(""); } From a5d41bc2ba845a277294def33ab6206e75e05923 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Wed, 14 Apr 2021 14:55:56 -0400 Subject: [PATCH 5/6] review comments --- packages/babel-types/scripts/generators/docs.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/packages/babel-types/scripts/generators/docs.js b/packages/babel-types/scripts/generators/docs.js index d081d5036eca..788d5718c1dc 100644 --- a/packages/babel-types/scripts/generators/docs.js +++ b/packages/babel-types/scripts/generators/docs.js @@ -178,7 +178,7 @@ function generateMapAliasToNodeTypes() { const aliasDescriptions = { Binary: "A cover of BinaryExpression and LogicalExpression, which share the same AST shape.", - Block: "A cover of BlockStatement and its alike.", + Block: "Deprecated. Will be removed in Babel 8.", BlockParent: "A cover of AST nodes that start an execution context with new [LexicalEnvironment](https://tc39.es/ecma262/#table-additional-state-components-for-ecmascript-code-execution-contexts). In other words, they define the scope of `let` and `const` declarations.", Class: @@ -189,16 +189,14 @@ const aliasDescriptions = { "A cover of ConditionalExpression and IfStatement, which share the same AST shape.", Declaration: "A cover of any [Declaration](https://tc39.es/ecma262/#prod-Declaration)s.", - EnumBody: - "A cover of enum bodies defined in [TypeScript](https://www.typescriptlang.org/docs/handbook/enums.html) and Flow.", - EnumMember: - "A cover of enum membors defined in [TypeScript](https://www.typescriptlang.org/docs/handbook/enums.html) and Flow.", + EnumBody: "A cover of Flow enum bodies.", + EnumMember: "A cover of Flow enum membors.", ExportDeclaration: "A cover of any [ExportDeclaration](https://tc39.es/ecma262/#prod-ExportDeclaration)s.", Expression: "A cover of any [Expression](https://tc39.es/ecma262/#sec-ecmascript-language-expressions)s.", ExpressionWrapper: - "A wrapper of expression that does not have run semantics.", + "A wrapper of expression that does not have runtime semantics.", Flow: "A cover of AST nodes defined for Flow.", FlowBaseAnnotation: "A cover of primary Flow type annotations.", FlowDeclaration: "A cover of Flow declarations.", @@ -212,7 +210,8 @@ const aliasDescriptions = { "A cover of functions and [method](#method)s, the must have `body` and `params`. Note: `Function` is different to `FunctionParent`.", FunctionParent: "A cover of AST nodes that start an execution context with new [VariableEnvironment](https://tc39.es/ecma262/#table-additional-state-components-for-ecmascript-code-execution-contexts). In other words, they define the scope of `var` declarations. FunctionParent did not include `Program` since Babel 7.", - Immutable: "A cover of immutable AST nodes.", + Immutable: + "A cover of immutable objects and JSX elements. An object is [immutable](https://tc39.es/ecma262/#immutable-prototype-exotic-object) if no other properties can be defined once created.", JSX: "A cover of AST nodes defined for [JSX](https://facebook.github.io/jsx/).", LVal: @@ -246,7 +245,7 @@ const aliasDescriptions = { Terminatorless: "A cover of AST nodes whose semantic will change when a line terminator is inserted between the operator and the operand.", UnaryLike: "A cover of UnaryExpression and SpreadElement.", - UserWhitespacable: "", + UserWhitespacable: "Deprecated. Will be removed in Babel 8.", While: "A cover of DoWhileStatement and WhileStatement, which share the same AST shape.", }; From e8ebe5708094e037dd6b5b2d500566f2703fabbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Wed, 14 Apr 2021 15:02:19 -0400 Subject: [PATCH 6/6] tiny tweaks --- packages/babel-types/scripts/generators/docs.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/babel-types/scripts/generators/docs.js b/packages/babel-types/scripts/generators/docs.js index 788d5718c1dc..1b2b8e2d5d0c 100644 --- a/packages/babel-types/scripts/generators/docs.js +++ b/packages/babel-types/scripts/generators/docs.js @@ -233,9 +233,9 @@ const aliasDescriptions = { Private: "A cover of private class elements and private identifiers.", Property: "A cover of object properties and class properties.", Pureish: - "A cover of AST nodes which does not have side-effect. In other words, there is no observable behaviour changes if they are evaluated more than once.", + "A cover of AST nodes which do not have side-effects. In other words, there is no observable behaviour changes if they are evaluated more than once.", Scopable: - "A cover of [FunctionParent](#FunctionParent) and [BlockParent](#BlockParent).", + "A cover of [FunctionParent](#functionparent) and [BlockParent](#blockparent).", Statement: "A cover of any [Statement](https://tc39.es/ecma262/#prod-Statement)s.", TSBaseType: "A cover of primary TypeScript type annotations.",