refactoring: introduce path.match (#7108)

This commit is contained in:
Georgii Dolzhykov authored and GitHub committed 2019-12-10 01:41:03 +02:00
1 parent f8928ec32a
commit db78483df1
4 files changed
+83 -102

No files matched your search

+36
View File
@@ -138,4 +138,40 @@ FastPath.prototype.map = function map(callback /*, name1, name2, ... */) {
return result;
};
/**
* @param {...(
* | ((node: any, name: string | null, number: number | null) => boolean)
* | undefined
* )} predicates
*/
FastPath.prototype.match = function match(/* predicates */) {
let stackPointer = this.stack.length - 1;
let name = null;
let node = this.stack[stackPointer--];
for (let i = 0; i < arguments.length; ++i) {
if (node === undefined) {
return false;
}
// skip index/array
let number = null;
if (typeof name === "number") {
number = name;
name = this.stack[stackPointer--];
node = this.stack[stackPointer--];
}
if (arguments[i] && !arguments[i](node, name, number)) {
return false;
}
name = this.stack[stackPointer--];
node = this.stack[stackPointer--];
}
return true;
};
module.exports = FastPath;
-15
View File
@@ -779,20 +779,6 @@ function hasNodeIgnoreComment(node) {
);
}
function matchAncestorTypes(path, types, index) {
index = index || 0;
types = types.slice();
while (types.length) {
const parent = path.getParentNode(index);
const type = types.shift();
if (!parent || parent.type !== type) {
return false;
}
index++;
}
return true;
}
function addCommentHelper(node, comment) {
const comments = node.comments || (node.comments = []);
comments.push(comment);
@@ -891,7 +877,6 @@ module.exports = {
hasIgnoreComment,
hasNodeIgnoreComment,
makeString,
matchAncestorTypes,
addLeadingComment,
addDanglingComment,
addTrailingComment,
+29 -64
View File
@@ -389,43 +389,37 @@ function isStyledJsx(path) {
* })
*/
function isAngularComponentStyles(path) {
return isPathMatch(
path,
[
node => node.type === "TemplateLiteral",
(node, name) => node.type === "ArrayExpression" && name === "elements",
(node, name) =>
node.type === "Property" &&
node.key.type === "Identifier" &&
node.key.name === "styles" &&
name === "value"
].concat(getAngularComponentObjectExpressionPredicates())
return path.match(
node => node.type === "TemplateLiteral",
(node, name) => node.type === "ArrayExpression" && name === "elements",
(node, name) =>
node.type === "Property" &&
node.key.type === "Identifier" &&
node.key.name === "styles" &&
name === "value",
...angularComponentObjectExpressionPredicates
);
}
function isAngularComponentTemplate(path) {
return isPathMatch(
path,
[
node => node.type === "TemplateLiteral",
(node, name) =>
node.type === "Property" &&
node.key.type === "Identifier" &&
node.key.name === "template" &&
name === "value"
].concat(getAngularComponentObjectExpressionPredicates())
return path.match(
node => node.type === "TemplateLiteral",
(node, name) =>
node.type === "Property" &&
node.key.type === "Identifier" &&
node.key.name === "template" &&
name === "value",
...angularComponentObjectExpressionPredicates
);
}
function getAngularComponentObjectExpressionPredicates() {
return [
(node, name) => node.type === "ObjectExpression" && name === "properties",
(node, name) =>
node.type === "CallExpression" &&
node.callee.type === "Identifier" &&
node.callee.name === "Component" &&
name === "arguments",
(node, name) => node.type === "Decorator" && name === "expression"
];
}
const angularComponentObjectExpressionPredicates = [
(node, name) => node.type === "ObjectExpression" && name === "properties",
(node, name) =>
node.type === "CallExpression" &&
node.callee.type === "Identifier" &&
node.callee.name === "Component" &&
name === "arguments",
(node, name) => node.type === "Decorator" && name === "expression"
];
/**
* styled-components template literals
@@ -536,50 +530,21 @@ function hasLanguageComment(node, languageName) {
);
}
function isPathMatch(path, predicateStack) {
const stack = path.stack.slice();
let name = null;
let node = stack.pop();
for (const predicate of predicateStack) {
if (node === undefined) {
return false;
}
// skip index/array
if (typeof name === "number") {
name = stack.pop();
node = stack.pop();
}
if (!predicate(node, name)) {
return false;
}
name = stack.pop();
node = stack.pop();
}
return true;
}
/**
* - html`...`
* - HTML comment block
*/
function isHtml(path) {
const node = path.getValue();
return (
hasLanguageComment(node, "HTML") ||
isPathMatch(path, [
hasLanguageComment(path.getValue(), "HTML") ||
path.match(
node => node.type === "TemplateLiteral",
(node, name) =>
node.type === "TaggedTemplateExpression" &&
node.tag.type === "Identifier" &&
node.tag.name === "html" &&
name === "quasi"
])
)
);
}
+18 -23
View File
@@ -20,7 +20,6 @@ const {
getPenultimate,
startsWithNoLookaheadToken,
getIndentSize,
matchAncestorTypes,
getPreferredQuote
} = require("../common/util");
const {
@@ -1406,18 +1405,19 @@ function printPathNoParens(path, options, print, args) {
// If we inline the object as first argument of the parent, we don't want
// to create another group so that the object breaks before the return
// type
const parentParentParent = path.getParentNode(2);
if (
(n.type === "ObjectPattern" &&
parent &&
shouldHugArguments(parent) &&
!n.decorators &&
parent.params[0] === n) ||
(shouldHugType(n) &&
parentParentParent &&
shouldHugArguments(parentParentParent) &&
parentParentParent.params[0].typeAnnotation &&
parentParentParent.params[0].typeAnnotation.typeAnnotation === n)
path.match(
node => node.type === "ObjectPattern" && !node.decorators,
(node, name, number) =>
shouldHugArguments(node) && name === "params" && number === 0
) ||
path.match(
shouldHugType,
(node, name) => name === "typeAnnotation",
(node, name) => name === "typeAnnotation",
(node, name, number) =>
shouldHugArguments(node) && name === "params" && number === 0
)
) {
return content;
}
@@ -5563,17 +5563,12 @@ function maybeWrapJSXElementInParens(path, elem, options) {
return elem;
}
const shouldBreak =
matchAncestorTypes(path, [
"ArrowFunctionExpression",
"CallExpression",
"JSXExpressionContainer"
]) ||
matchAncestorTypes(path, [
"ArrowFunctionExpression",
"OptionalCallExpression",
"JSXExpressionContainer"
]);
const shouldBreak = path.match(
undefined,
node => node.type === "ArrowFunctionExpression",
isCallOrOptionalCallExpression,
node => node.type === "JSXExpressionContainer"
);
const needsParens = pathNeedsParens(path, options);