Switch js parse postprocess to onEnter (#18382)
This commit is contained in:
1 parent
d3eb2b2d08
commit
706aa4ef90
7 files changed
+70
-49
No files matched your search
@@ -1,4 +1,5 @@
|
||||
import PostcssValuesParser from "postcss-values-parser/lib/parser.js";
|
||||
import isObject from "../../utilities/is-object.js";
|
||||
import getFunctionArgumentsText from "../utilities/get-function-arguments-text.js";
|
||||
import getValueRoot from "../utilities/get-value-root.js";
|
||||
import hasSCSSInterpolation from "../utilities/has-scss-interpolation.js";
|
||||
@@ -156,7 +157,7 @@ function flattenGroups(node) {
|
||||
}
|
||||
|
||||
function parseNestedValue(node, options) {
|
||||
if (node && typeof node === "object") {
|
||||
if (isObject(node)) {
|
||||
for (const key in node) {
|
||||
if (key !== "parent") {
|
||||
parseNestedValue(node[key], options);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import isObject from "../../utilities/is-object.js";
|
||||
|
||||
function addTypePrefix(node, prefix, skipPrefix) {
|
||||
if (node && typeof node === "object") {
|
||||
if (isObject(node)) {
|
||||
delete node.parent;
|
||||
for (const key in node) {
|
||||
addTypePrefix(node[key], prefix, skipPrefix);
|
||||
@@ -17,7 +19,7 @@ function addTypePrefix(node, prefix, skipPrefix) {
|
||||
}
|
||||
|
||||
function addMissingType(node) {
|
||||
if (node && typeof node === "object") {
|
||||
if (isObject(node)) {
|
||||
delete node.parent;
|
||||
for (const key in node) {
|
||||
addMissingType(node[key]);
|
||||
|
||||
@@ -3,6 +3,7 @@ import postcssLess from "postcss-less";
|
||||
import postcssScssParse from "postcss-scss/lib/scss-parse";
|
||||
import createError from "../common/parser-create-error.js";
|
||||
import { parseFrontMatter } from "../main/front-matter/index.js";
|
||||
import isObject from "../utilities/is-object.js";
|
||||
import {
|
||||
calculateLoc,
|
||||
locEnd,
|
||||
@@ -21,7 +22,7 @@ const DEFAULT_SCSS_DIRECTIVE = /(\s*)(!default).*$/u;
|
||||
const GLOBAL_SCSS_DIRECTIVE = /(\s*)(!global).*$/u;
|
||||
|
||||
function parseNestedCSS(node, options) {
|
||||
if (node && typeof node === "object") {
|
||||
if (isObject(node)) {
|
||||
delete node.parent;
|
||||
|
||||
for (const key in node) {
|
||||
|
||||
@@ -43,10 +43,31 @@ function postprocess(ast, options) {
|
||||
|
||||
mergeNestledJsdocComments(comments);
|
||||
|
||||
// `InterpreterDirective` from babel parser and flow parser
|
||||
// Other parsers parse it as comment, babel treat it as comment too
|
||||
// https://github.com/babel/babel/issues/15116
|
||||
const program = ast.type === "File" ? ast.program : ast;
|
||||
if (program.interpreter) {
|
||||
comments.unshift(program.interpreter);
|
||||
delete program.interpreter;
|
||||
}
|
||||
|
||||
if (isOxcTs && ast.hashbang) {
|
||||
comments.unshift(ast.hashbang);
|
||||
delete ast.hashbang;
|
||||
}
|
||||
|
||||
// In `typescript` and `flow`, `Program` doesn't count whitespace and comments
|
||||
// See https://github.com/typescript-eslint/typescript-eslint/issues/11026
|
||||
// See https://github.com/facebook/flow/issues/8537
|
||||
if (ast.type === "Program") {
|
||||
ast.range = [0, text.length];
|
||||
}
|
||||
|
||||
let typeCastCommentsEnds;
|
||||
|
||||
ast = visitNode(ast, {
|
||||
onLeave(node) {
|
||||
onEnter(node) {
|
||||
switch (node.type) {
|
||||
case "ParenthesizedExpression": {
|
||||
const { expression } = node;
|
||||
@@ -58,7 +79,7 @@ function postprocess(ast, options) {
|
||||
return expression;
|
||||
}
|
||||
|
||||
let keepTypeCast = false;
|
||||
let shouldKeepParenthesizedExpression = false;
|
||||
if (!isOxcTs) {
|
||||
if (!typeCastCommentsEnds) {
|
||||
typeCastCommentsEnds = [];
|
||||
@@ -74,27 +95,21 @@ function postprocess(ast, options) {
|
||||
const previousCommentEnd = typeCastCommentsEnds.findLast(
|
||||
(end) => end <= start,
|
||||
);
|
||||
keepTypeCast =
|
||||
shouldKeepParenthesizedExpression =
|
||||
previousCommentEnd &&
|
||||
// check that there are only white spaces between the comment and the parenthesis
|
||||
text.slice(previousCommentEnd, start).trim().length === 0;
|
||||
}
|
||||
|
||||
if (!keepTypeCast) {
|
||||
expression.extra = { ...expression.extra, parenthesized: true };
|
||||
return expression;
|
||||
if (shouldKeepParenthesizedExpression) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
expression.extra = { ...expression.extra, parenthesized: true };
|
||||
return expression;
|
||||
}
|
||||
|
||||
case "LogicalExpression":
|
||||
// We remove unneeded parens around same-operator LogicalExpressions
|
||||
if (isUnbalancedLogicalTree(node)) {
|
||||
return rebalanceLogicalTree(node);
|
||||
}
|
||||
break;
|
||||
|
||||
// This happens when use `oxc-parser` to parse `` `${foo satisfies bar}`; ``
|
||||
// This happened when use `oxc-parser` to parse `` `${foo satisfies bar}`; ``
|
||||
// https://github.com/oxc-project/oxc/issues/11313
|
||||
case "TemplateLiteral":
|
||||
/* c8 ignore next 3 */
|
||||
@@ -128,6 +143,7 @@ function postprocess(ast, options) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// remove redundant TypeScript nodes
|
||||
case "TSParenthesizedType":
|
||||
return node.typeAnnotation;
|
||||
@@ -135,9 +151,7 @@ function postprocess(ast, options) {
|
||||
// For hack-style pipeline
|
||||
case "TopicReference":
|
||||
ast.extra = { ...ast.extra, __isUsingHackPipeline: true };
|
||||
break;
|
||||
|
||||
// In Flow parser, it doesn't generate union/intersection types for single type
|
||||
break; // In Flow parser, it doesn't generate union/intersection types for single type
|
||||
case "TSUnionType":
|
||||
case "TSIntersectionType":
|
||||
if (node.types.length === 1) {
|
||||
@@ -151,9 +165,21 @@ function postprocess(ast, options) {
|
||||
node.options = node.attributes;
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
onLeave(node) {
|
||||
switch (node.type) {
|
||||
// Children can be parenthesized, need do this in `onLeave`
|
||||
case "LogicalExpression":
|
||||
// We remove unneeded parens around same-operator LogicalExpressions
|
||||
if (isUnbalancedLogicalTree(node)) {
|
||||
return rebalanceLogicalTree(node);
|
||||
}
|
||||
break;
|
||||
|
||||
// https://github.com/babel/babel/issues/17506
|
||||
// https://github.com/oxc-project/oxc/issues/16074
|
||||
// It's possible to have parenthesized `argument`, need do this in `onLeave`
|
||||
case "TSImportType":
|
||||
if (!node.source && node.argument.type === "TSLiteralType") {
|
||||
node.source = node.argument.literal;
|
||||
@@ -169,31 +195,10 @@ function postprocess(ast, options) {
|
||||
},
|
||||
});
|
||||
|
||||
// `InterpreterDirective` from babel parser and flow parser
|
||||
// Other parsers parse it as comment, babel treat it as comment too
|
||||
// https://github.com/babel/babel/issues/15116
|
||||
const program = ast.type === "File" ? ast.program : ast;
|
||||
if (program.interpreter) {
|
||||
comments.unshift(program.interpreter);
|
||||
delete program.interpreter;
|
||||
}
|
||||
|
||||
if (isOxcTs && ast.hashbang) {
|
||||
comments.unshift(ast.hashbang);
|
||||
delete ast.hashbang;
|
||||
}
|
||||
|
||||
/* c8 ignore next 3 */
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
assertComments(comments, text);
|
||||
}
|
||||
|
||||
// In `typescript` and `flow`, `Program` doesn't count whitespace and comments
|
||||
// See https://github.com/typescript-eslint/typescript-eslint/issues/11026
|
||||
// See https://github.com/facebook/flow/issues/8537
|
||||
if (ast.type === "Program") {
|
||||
ast.range = [0, text.length];
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import isObject from "../../../utilities/is-object.js";
|
||||
import getVisitorKeys from "../../traverse/get-visitor-keys.js";
|
||||
|
||||
function visitNode(node, options) {
|
||||
if (!(node !== null && typeof node === "object")) {
|
||||
if (!isObject(node)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -16,7 +17,13 @@ function visitNode(node, options) {
|
||||
}
|
||||
|
||||
if (options.onEnter) {
|
||||
node = options.onEnter(node) || node;
|
||||
const result = options.onEnter(node) ?? node;
|
||||
// If node is replaced, re-enter
|
||||
if (result !== node) {
|
||||
return visitNode(result, options);
|
||||
}
|
||||
|
||||
node = result;
|
||||
}
|
||||
|
||||
const keys = getVisitorKeys(node);
|
||||
@@ -24,7 +31,11 @@ function visitNode(node, options) {
|
||||
node[keys[i]] = visitNode(node[keys[i]], options);
|
||||
}
|
||||
|
||||
return options.onLeave(node) || node;
|
||||
if (options.onLeave) {
|
||||
node = options.onLeave(node) || node;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
export default visitNode;
|
||||
@@ -3,6 +3,7 @@ import getStringWidth from "../../utilities/get-string-width.js";
|
||||
import hasNewline from "../../utilities/has-newline.js";
|
||||
import isNextLineEmptyAfterIndex from "../../utilities/is-next-line-empty.js";
|
||||
import isNonEmptyArray from "../../utilities/is-non-empty-array.js";
|
||||
import isObject from "../../utilities/is-object.js";
|
||||
import printString from "../../utilities/print-string.js";
|
||||
import { hasSameLocStart, locEnd, locStart } from "../loc.js";
|
||||
import getVisitorKeys from "../traverse/get-visitor-keys.js";
|
||||
@@ -417,7 +418,7 @@ function getExpressionInnerNodeCount(node, maxCount) {
|
||||
for (const k in node) {
|
||||
const prop = node[k];
|
||||
|
||||
if (prop && typeof prop === "object" && typeof prop.type === "string") {
|
||||
if (isObject(prop) && typeof prop.type === "string") {
|
||||
count++;
|
||||
count += getExpressionInnerNodeCount(prop, maxCount - count);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import AstPath from "../common/ast-path.js";
|
||||
import { cursor, inheritLabel } from "../document/index.js";
|
||||
import isObject from "../utilities/is-object.js";
|
||||
import { attachComments } from "./comments/attach.js";
|
||||
import { ensureAllCommentsPrinted, printComments } from "./comments/print.js";
|
||||
import createPrintPreCheckFunction from "./create-print-pre-check-function.js";
|
||||
@@ -82,8 +83,7 @@ async function printAstToDoc(ast, options) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const shouldCache =
|
||||
value && typeof value === "object" && args === undefined;
|
||||
const shouldCache = isObject(value) && args === undefined;
|
||||
|
||||
if (shouldCache && cache.has(value)) {
|
||||
return cache.get(value);
|
||||
|
||||
Reference in new issue
Block a user