Skip to content

Commit

Permalink
chore(Masthead): cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
wise-king-sullyman committed Aug 2, 2024
1 parent 4c45148 commit 0062d93
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 128 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { ImportSpecifier, JSXOpeningElement } from "estree-jsx";

/** Resolves the imported name of a node, even if that node has an aliased local name */
export function getImportedName(
namedImports: ImportSpecifier[],
node: JSXOpeningElement
) {
if (node.name.type !== "JSXIdentifier") {
return;
}

const nodeName = node.name.name;

const nodeImport = namedImports.find((imp) => imp.local.name === nodeName);

return nodeImport?.imported.name;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { ImportSpecifier } from "estree-jsx";

/** Resolves the local name of an import */
export function getLocalComponentName(
namedImports: ImportSpecifier[],
importedName: string
) {
const componentImport = namedImports.find(
(name) => name.imported.name === importedName
);

const isAlias =
componentImport?.imported.name !== componentImport?.local.name;

if (componentImport && isAlias) {
return componentImport.local.name;
}

return importedName;
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import { Rule } from "eslint";
import {
ImportDefaultSpecifier,
ImportSpecifier,
JSXAttribute,
JSXElement,
JSXIdentifier,
JSXMemberExpression,
JSXNamespacedName,
JSXOpeningElement,
} from "estree-jsx";
import { getAllImportsFromPackage, getChildElementByName } from "../../helpers";
import { stringifyJSXElement } from "../../helpers/stringifyJSXElement";
import { ImportDefaultSpecifierWithParent } from "../../helpers";
import { getImportedName } from "../../helpers/getImportedName";
import { getLocalComponentName } from "../../helpers/getLocalComponentName";
// https://github.com/patternfly/patternfly-react/pull/10809

// new interfaces, just local for now to avoid conflicts with the masthead rename RP
Expand Down Expand Up @@ -44,67 +41,22 @@ function hasCodeModDataTag(openingElement: JSXOpeningElement) {
return attributeNames.includes("data-codemods");
}

// Similar story here, will use the getName helper from my other PR once it goes in
function getName(
nodeName: JSXIdentifier | JSXMemberExpression | JSXNamespacedName
) {
switch (nodeName.type) {
case "JSXIdentifier":
return nodeName.name;
case "JSXMemberExpression":
return getName(nodeName.object);
case "JSXNamespacedName":
return nodeName.namespace.name;
}
}

// and here
function getDeclarationString(
defaultImportSpecifier: ImportDefaultSpecifierWithParent
) {
return defaultImportSpecifier?.parent?.source.value?.toString();
}
// and here
function getComponentImportName(
importSpecifier: ImportSpecifier | ImportDefaultSpecifierWithParent,
potentialNames: string[]
) {
if (importSpecifier.type === "ImportSpecifier") {
return importSpecifier.imported.name;
}

return potentialNames.find((name) =>
getDeclarationString(importSpecifier)?.includes(name)
);
}

// "real" code starts here
function moveNodeIntoMastheadMain(
context: Rule.RuleContext,
fixer: Rule.RuleFixer,
node: JSXOpeningElementWithParent,
componentImports: (ImportSpecifier | ImportDefaultSpecifier)[]
namedImports: ImportSpecifier[]
) {
if (!node.parent || !node.parent.parent) {
return [];
}

const namedImports = componentImports.filter(
(imp) => imp.type === "ImportSpecifier"
);

const mastheadMainImport = namedImports.find(
(name) => (name as ImportSpecifier).imported.name === "MastheadMain"
const localMastheadMain = getLocalComponentName(namedImports, "MastheadMain");
const mastheadMain = getChildElementByName(
node.parent.parent,
localMastheadMain
);
const isAlias =
(mastheadMainImport as ImportSpecifier)?.imported.name !==
mastheadMainImport?.local.name;

const componentName =
mastheadMainImport && isAlias
? mastheadMainImport.local.name
: "MastheadMain";

const mastheadMain = getChildElementByName(node.parent.parent, componentName);

if (!mastheadMain) {
return [];
Expand All @@ -122,7 +74,7 @@ function moveNodeIntoMastheadMain(
function wrapNodeInMastheadBrand(
fixer: Rule.RuleFixer,
node: JSXOpeningElementWithParent,
componentImports: (ImportSpecifier | ImportDefaultSpecifier)[]
namedImports: ImportSpecifier[]
) {
if (!node.parent) {
return [];
Expand All @@ -134,29 +86,20 @@ function wrapNodeInMastheadBrand(
? node.parent.closingElement
: node;

const importCount = componentImports.length - 1;
const lastImport = componentImports[importCount];
const importCount = namedImports.length - 1;
const lastImport = namedImports[importCount];

const namedImports = componentImports.filter(
(imp) => imp.type === "ImportSpecifier"
const localMastheadBrand = getLocalComponentName(
namedImports,
"MastheadBrand"
);

const mastheadBrandImport = namedImports.find(
(name) => (name as ImportSpecifier).imported.name === "MastheadBrand"
fixes.push(
fixer.insertTextBefore(node, `<${localMastheadBrand} data-codemods>`)
);
const isAlias =
(mastheadBrandImport as ImportSpecifier)?.imported.name !==
mastheadBrandImport?.local.name;

const componentName =
mastheadBrandImport && isAlias
? mastheadBrandImport.local.name
: "MastheadBrand";
fixes.push(fixer.insertTextAfter(closingNode, `</${localMastheadBrand}>`));

fixes.push(fixer.insertTextBefore(node, `<${componentName} data-codemods>`));
fixes.push(fixer.insertTextAfter(closingNode, `</${componentName}>`));

if (!mastheadBrandImport) {
if (!namedImports.some((imp) => imp.imported.name === "MastheadBrand")) {
fixes.push(fixer.insertTextAfter(lastImport, ", MastheadBrand"));
}

Expand All @@ -171,45 +114,29 @@ module.exports = {
"MastheadToggle",
"MastheadLogo",
"Masthead",
"MastheadMain"
"MastheadMain",
];
const componentImports = getAllImportsFromPackage(
context,
"@patternfly/react-core",
targetComponents
);
const _namedImports = componentImports.filter(
(imp) => imp.type === "ImportSpecifier"
);
// TS isn't properly resolving that namedImports is just ImportSpecifiers, hence this seemingly unneeded assertion
const namedImports = _namedImports as ImportSpecifier[];

const message =
"The structure of Masthead has been updated, MastheadToggle and MastheadBrand should now be wrapped in MastheadMain.";

function isPFImport(
node: JSXOpeningElementWithParent,
potentialComponentNames: string[]
) {
const nodeName = getName(node.name);
const nodeImport = componentImports.find(
(imp) => imp.local.name === nodeName
);

if (!(nodeImport?.type === "ImportSpecifier")) {
return false;
}

const nodeImportedName = nodeImport.imported.name;

return componentImports
.map((imp) => getComponentImportName(imp, potentialComponentNames))
.includes(nodeImportedName);
}

return !componentImports.length
return !namedImports.length
? {}
: {
JSXOpeningElement(node: JSXOpeningElementWithParent) {
if (
node.name.type !== "JSXIdentifier" ||
!isPFImport(node, targetComponents)
) {
const nodeImportedName = getImportedName(namedImports, node);

if (node.name.type !== "JSXIdentifier" || !nodeImportedName) {
return;
}
const parentOpeningElement = node.parent?.parent?.openingElement;
Expand All @@ -218,27 +145,10 @@ module.exports = {
return;
}

const nodeName = node.name.name;

const nodeImport = componentImports.find(
(imp) => imp.local.name === nodeName
);

const nodeImportedName =
nodeImport?.type === "ImportSpecifier" &&
nodeImport.imported.name;

const parentName =
parentOpeningElement.name.type === "JSXIdentifier" &&
parentOpeningElement.name.name;

const parentImport = componentImports.find(
(imp) => imp.local.name === parentName
const parentImportedName = getImportedName(
namedImports,
parentOpeningElement
);

const parentImportedName =
parentImport?.type === "ImportSpecifier" &&
parentImport.imported.name;

if (
nodeImportedName === "MastheadToggle" &&
Expand All @@ -248,12 +158,7 @@ module.exports = {
node,
message,
fix: (fixer) =>
moveNodeIntoMastheadMain(
context,
fixer,
node,
componentImports
),
moveNodeIntoMastheadMain(context, fixer, node, namedImports),
});
return;
}
Expand All @@ -272,7 +177,7 @@ module.exports = {
node,
message,
fix: (fixer) =>
wrapNodeInMastheadBrand(fixer, node, componentImports),
wrapNodeInMastheadBrand(fixer, node, namedImports),
});
}
},
Expand Down

0 comments on commit 0062d93

Please sign in to comment.