refactor: 処理共通化
This commit is contained in:
parent
efb50f03d9
commit
d8cd69e055
|
|
@ -13,88 +13,69 @@ import * as ts from 'typescript';
|
||||||
export function removeNeverPropertiesFromAST(astNodes: readonly ts.Node[]): ts.Node[] {
|
export function removeNeverPropertiesFromAST(astNodes: readonly ts.Node[]): ts.Node[] {
|
||||||
const factory = ts.factory;
|
const factory = ts.factory;
|
||||||
|
|
||||||
const typeNodeRecursiveVisitor = (node: ts.Node): ts.Node | undefined => {
|
/**
|
||||||
if (ts.isTypeLiteralNode(node)) {
|
* TypeLiteralNodeやInterfaceDeclarationのmembersからneverプロパティを除去し、必要なら型も再帰的に処理する共通関数
|
||||||
const newMembers: ts.TypeElement[] = [];
|
*/
|
||||||
let hasTypeLiteralChanged = false;
|
function removeNeverPropertiesFromMembers(
|
||||||
|
members: readonly ts.TypeElement[],
|
||||||
|
visitType: (node: ts.Node) => ts.Node | undefined,
|
||||||
|
): { newMembers: ts.TypeElement[]; hasChanged: boolean } {
|
||||||
|
const newMembers: ts.TypeElement[] = [];
|
||||||
|
let hasChanged = false;
|
||||||
|
|
||||||
for (const member of node.members) {
|
for (const member of members) {
|
||||||
if (ts.isPropertySignature(member)) {
|
if (ts.isPropertySignature(member)) {
|
||||||
if (member.type && member.type.kind === ts.SyntaxKind.NeverKeyword) {
|
if (member.type && member.type.kind === ts.SyntaxKind.NeverKeyword) {
|
||||||
hasTypeLiteralChanged = true;
|
hasChanged = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let updatedPropertySignature = member;
|
||||||
|
if (member.type) {
|
||||||
|
const visitedMemberType = ts.visitNode(member.type, visitType);
|
||||||
|
if (visitedMemberType && visitedMemberType !== member.type) {
|
||||||
|
updatedPropertySignature = factory.updatePropertySignature(
|
||||||
|
member,
|
||||||
|
member.modifiers,
|
||||||
|
member.name,
|
||||||
|
member.questionToken,
|
||||||
|
visitedMemberType as ts.TypeNode,
|
||||||
|
);
|
||||||
|
hasChanged = true;
|
||||||
|
} else if (visitedMemberType === undefined) {
|
||||||
|
// 子の型が消された場合、このプロパティも消す
|
||||||
|
hasChanged = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let updatedPropertySignature = member;
|
|
||||||
if (member.type) {
|
|
||||||
const visitedMemberType = ts.visitNode(member.type, typeNodeRecursiveVisitor);
|
|
||||||
if (visitedMemberType && visitedMemberType !== member.type) {
|
|
||||||
updatedPropertySignature = factory.updatePropertySignature(
|
|
||||||
member,
|
|
||||||
member.modifiers,
|
|
||||||
member.name,
|
|
||||||
member.questionToken,
|
|
||||||
visitedMemberType as ts.TypeNode
|
|
||||||
);
|
|
||||||
hasTypeLiteralChanged = true;
|
|
||||||
} else if (visitedMemberType === undefined) {
|
|
||||||
// 子の型が消された場合、このプロパティも消す
|
|
||||||
hasTypeLiteralChanged = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
newMembers.push(updatedPropertySignature);
|
|
||||||
} else {
|
|
||||||
newMembers.push(member);
|
|
||||||
}
|
}
|
||||||
|
newMembers.push(updatedPropertySignature);
|
||||||
|
} else {
|
||||||
|
newMembers.push(member);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return { newMembers, hasChanged };
|
||||||
|
}
|
||||||
|
|
||||||
|
function typeNodeRecursiveVisitor(node: ts.Node): ts.Node | undefined {
|
||||||
|
if (ts.isTypeLiteralNode(node)) {
|
||||||
|
const { newMembers, hasChanged } = removeNeverPropertiesFromMembers(node.members, typeNodeRecursiveVisitor);
|
||||||
|
|
||||||
if (newMembers.length === 0) {
|
if (newMembers.length === 0) {
|
||||||
// すべてのプロパティがneverで消された場合、このTypeLiteralNode自体も消す
|
// すべてのプロパティがneverで消された場合、このTypeLiteralNode自体も消す
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasTypeLiteralChanged) {
|
if (hasChanged) {
|
||||||
return factory.updateTypeLiteralNode(node, factory.createNodeArray(newMembers));
|
return factory.updateTypeLiteralNode(node, factory.createNodeArray(newMembers));
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ts.visitEachChild(node, typeNodeRecursiveVisitor, undefined);
|
return ts.visitEachChild(node, typeNodeRecursiveVisitor, undefined);
|
||||||
};
|
}
|
||||||
|
|
||||||
const interfaceRecursiveVisitor = (node: ts.Node): ts.Node | undefined => {
|
function interfaceRecursiveVisitor(node: ts.Node): ts.Node | undefined {
|
||||||
if (ts.isInterfaceDeclaration(node)) {
|
if (ts.isInterfaceDeclaration(node)) {
|
||||||
const newMembers: ts.TypeElement[] = [];
|
const { newMembers, hasChanged } = removeNeverPropertiesFromMembers(node.members, typeNodeRecursiveVisitor);
|
||||||
let hasChanged = false;
|
|
||||||
|
|
||||||
for (const member of node.members) {
|
|
||||||
if (ts.isPropertySignature(member)) {
|
|
||||||
if (member.type && member.type.kind === ts.SyntaxKind.NeverKeyword) {
|
|
||||||
hasChanged = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let updatedPropertySignature = member;
|
|
||||||
if (member.type) {
|
|
||||||
const visitedMemberType = ts.visitNode(member.type, typeNodeRecursiveVisitor);
|
|
||||||
if (visitedMemberType && visitedMemberType !== member.type) {
|
|
||||||
updatedPropertySignature = factory.updatePropertySignature(
|
|
||||||
member,
|
|
||||||
member.modifiers,
|
|
||||||
member.name,
|
|
||||||
member.questionToken,
|
|
||||||
visitedMemberType as ts.TypeNode
|
|
||||||
);
|
|
||||||
hasChanged = true;
|
|
||||||
} else if (visitedMemberType === undefined) {
|
|
||||||
hasChanged = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
newMembers.push(updatedPropertySignature);
|
|
||||||
} else {
|
|
||||||
newMembers.push(member);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newMembers.length === 0) {
|
if (newMembers.length === 0) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|
@ -107,15 +88,15 @@ export function removeNeverPropertiesFromAST(astNodes: readonly ts.Node[]): ts.N
|
||||||
node.name,
|
node.name,
|
||||||
node.typeParameters,
|
node.typeParameters,
|
||||||
node.heritageClauses,
|
node.heritageClauses,
|
||||||
newMembers
|
newMembers,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
return ts.visitEachChild(node, interfaceRecursiveVisitor, undefined);
|
return ts.visitEachChild(node, interfaceRecursiveVisitor, undefined);
|
||||||
};
|
}
|
||||||
|
|
||||||
const topLevelVisitor = (node: ts.Node): ts.Node | undefined => {
|
function topLevelVisitor(node: ts.Node): ts.Node | undefined {
|
||||||
if (ts.isTypeAliasDeclaration(node) && node.name.escapedText === 'paths') {
|
if (ts.isTypeAliasDeclaration(node) && node.name.escapedText === 'paths') {
|
||||||
const newType = ts.visitNode(node.type, typeNodeRecursiveVisitor);
|
const newType = ts.visitNode(node.type, typeNodeRecursiveVisitor);
|
||||||
if (newType && newType !== node.type) {
|
if (newType && newType !== node.type) {
|
||||||
|
|
@ -124,7 +105,7 @@ export function removeNeverPropertiesFromAST(astNodes: readonly ts.Node[]): ts.N
|
||||||
node.modifiers,
|
node.modifiers,
|
||||||
node.name,
|
node.name,
|
||||||
node.typeParameters,
|
node.typeParameters,
|
||||||
newType as ts.TypeNode
|
newType as ts.TypeNode,
|
||||||
);
|
);
|
||||||
} else if (newType === undefined) {
|
} else if (newType === undefined) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|
@ -135,7 +116,7 @@ export function removeNeverPropertiesFromAST(astNodes: readonly ts.Node[]): ts.N
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return ts.visitEachChild(node, topLevelVisitor, undefined);
|
return ts.visitEachChild(node, topLevelVisitor, undefined);
|
||||||
};
|
}
|
||||||
|
|
||||||
const transformedNodes: ts.Node[] = [];
|
const transformedNodes: ts.Node[] = [];
|
||||||
for (const astNode of astNodes) {
|
for (const astNode of astNodes) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue