ts2famix
Version:
A TypeScript to JSON importer for Moose.
144 lines (127 loc) • 5.85 kB
text/typescript
import * as Famix from "../lib/famix/model/famix";
import { logger } from "../analyze";
import { ConstructorDeclaration, Identifier, FunctionDeclaration, MethodDeclaration, MethodSignature, PropertyDeclaration, PropertySignature, VariableDeclaration, ParameterDeclaration, GetAccessorDeclaration, SetAccessorDeclaration, EnumMember, TypeAliasDeclaration, Node, SyntaxKind, FunctionExpression } from "ts-morph";
import { TSMorphTypeDeclaration } from "./EntityDictionary";
interface SearchParameters {
searchArray: string[];
targetArray: string[];
start?: number;
}
/**
* This function works like indexOf, but it works with arrays of grapheme clusters.
* @param targetArray
*/
export function indexOfSplitArray(params: SearchParameters): number {
const {searchArray, targetArray, start = 0} = params;
for (let i = start; i <= searchArray.length - targetArray.length; i++) {
let found = true;
for (let j = 0; j < targetArray.length; j++) {
if (searchArray[i + j] !== targetArray[j]) {
found = false;
break;
}
}
if (found) {
return i; // Return the index where the target array was found
}
}
return -1; // Return -1 if the target array was not found in the search array
}
export function getSubTypeName(fmxNamedEntity: Famix.NamedEntity) {
const name = fmxNamedEntity instanceof Famix.Class ? 'Class' :
fmxNamedEntity instanceof Famix.Interface ? 'Interface' :
fmxNamedEntity instanceof Famix.Function ? 'Function' :
fmxNamedEntity instanceof Famix.Enum ? 'Enum' :
fmxNamedEntity instanceof Famix.EnumValue ? 'EnumValue' :
fmxNamedEntity instanceof Famix.Alias ? 'Alias' :
fmxNamedEntity instanceof Famix.Variable ? 'Variable' :
fmxNamedEntity instanceof Famix.Type ? 'Type' :
fmxNamedEntity instanceof Famix.Method ? 'Method' :
fmxNamedEntity instanceof Famix.Decorator ? 'Decorator' :
fmxNamedEntity instanceof Famix.Accessor ? 'Accessor' :
fmxNamedEntity instanceof Famix.Parameter ? 'Parameter' :
fmxNamedEntity instanceof Famix.Property ? 'Property' :
'NamedEntity';
logger.debug(`${fmxNamedEntity.name} is of type ${name}`);
return name;
}
/**
* Gets the signature of a method or a function
* @param text A method or a function source code
* @returns The signature of the method or the function
*/
export function computeSignature(text: string): string {
const endSignatureText = text.indexOf("{");
return text.substring(0, endSignatureText).trim();
}
/**
* Finds the ancestor of a node
* @param node A node
* @returns The ancestor of the node
*/
export function findAncestor(node: Identifier): Node {
let ancestor: Node | undefined;
ancestor = node.getAncestors().find(a =>
a.getKind() === SyntaxKind.MethodDeclaration ||
a.getKind() === SyntaxKind.Constructor ||
a.getKind() === SyntaxKind.FunctionDeclaration ||
a.getKind() === SyntaxKind.FunctionExpression ||
a.getKind() === SyntaxKind.ModuleDeclaration ||
a.getKind() === SyntaxKind.SourceFile ||
a.getKindName() === "GetAccessor" ||
a.getKindName() === "SetAccessor" ||
a.getKind() === SyntaxKind.ClassDeclaration);
if (!ancestor) {
throw new Error(`Ancestor not found for ${node.getText()}`);
}
return ancestor
}
/**
* Finds the ancestor of a ts-morph element
* @param element A ts-morph element
* @returns The ancestor of the ts-morph element
*/
export function findTypeAncestor(element: Node): Node | undefined {
let ancestor: Node | undefined;
const ancestors = element.getAncestors();
console.log(`Ancestors count: ${ancestors.length}`);
ancestor = ancestors.find(a => {
const kind = a.getKind();
const kindName = a.getKindName();
return kind === SyntaxKind.MethodDeclaration ||
kind === SyntaxKind.Constructor ||
kind === SyntaxKind.MethodSignature ||
kind === SyntaxKind.FunctionDeclaration ||
kind === SyntaxKind.FunctionExpression ||
kind === SyntaxKind.ModuleDeclaration ||
kind === SyntaxKind.SourceFile ||
kindName === "GetAccessor" ||
kindName === "SetAccessor" ||
kind === SyntaxKind.ClassDeclaration ||
kind === SyntaxKind.InterfaceDeclaration;
});
if (!ancestor) {
throw new Error(`Type ancestor not found for ${element.getKindName()}`);
}
return ancestor;
}
export function arraysAreEqual(array1: string[], array2: string[]): boolean {
if (array1 && array2 ) {
return array1.length === array2.length && array1.every((value, index) => value === array2[index]);
} else {
return false;
}
}
export function replaceLastBetweenTags(input: string, replacement: string): string {
const lastTagIndex = input.lastIndexOf('<');
if (lastTagIndex === -1) {
return input; // Return the original string if no tags are found
}
const closingTagIndex = input.indexOf('>', lastTagIndex);
if (closingTagIndex === -1) {
return input; // Return the original string if no closing tag is found
}
const beforeTag = input.substring(0, lastTagIndex + 1); // Include '<'
const afterTag = input.substring(closingTagIndex); // Include '>'
return beforeTag + replacement + afterTag;
}