-
Notifications
You must be signed in to change notification settings - Fork 0
Extraction Techniques
This section provides a detailed explanation of how SwiftGen uses ts-morph to extract function declarations from TypeScript files. These extracted functions are then converted and included in the generated Swift code.
npm install ts-morphImport ts-morph into your TypeScript project
import { Project } from "ts-morph";Initialize a new project with ts-morph and add the source files that you want to process.
function initializeProject(filePath: string) {
const project = new Project();
return project.addSourceFileAtPath(filePath);
}The core function for extracting variable declarations is extractVariables. This function retrieves all variable statements from the source file and maps each declaration to its name.
Here is the complete implementation of the extractVariables function:
function extractVariables(sourceFile: any) {
return sourceFile.getVariableStatements()
.flatMap((statement: any) => statement.getDeclarations().map((decl: any) => decl.getName()));
}- getVariableStatements: This method retrieves all variable statement nodes in the source file.
- flatMap: This method flattens the array of variable statements into an array of individual declarations.
- getDeclarations: This method retrieves all declarations within a variable statement.
- getName: This method retrieves the name of each variable declaration.
To use the extractVariables function, follow these steps:
- Initialize the project with the source file.
- Call
extractVariableswith the initialized source file.
const sourceFile = initializeProject("path/to/your/file.ts");
const variables = extractVariables(sourceFile);
console.log(variables);This will log an array of variable names found in the specified TypeScript file.
In SwiftGen, after extracting variables, these are combined with other extracted elements (functions, enums, type aliases) to generate the Swift code.
let combinedVariables: string[] = [];
inputFiles.forEach((filePath: string) => {
try {
const sourceFile = initializeProject(filePath);
combinedVariables = combinedVariables.concat(extractVariables(sourceFile));
} catch (error) {
console.error(`Error processing file ${filePath}:`, error);
}
});The main function for extracting function declarations is extractFunctions. This function retrieves all function nodes in the source file and maps them to an object containing the function name, parameters, and type parameters.
Here is the complete implementation of the extractFunctions function:
function extractFunctions(sourceFile: any) {
return sourceFile.getFunctions().map((func: any) => ({
name: func.getName(),
parameters: func.getParameters().map((param: any) => ({
name: param.getName(),
type: convertType(param.getType().getText()),
default: param.hasInitializer() ? param.getInitializer()?.getText() : undefined
})),
typeParameters: func.getTypeParameters().map((param: any) => param.getName())
}));
}- getFunctions: This method retrieves all function nodes in the source file.
- map: This method maps each function node to an object containing its details.
- getName: Retrieves the name of the function.
-
getParameters: Retrieves all parameters of the function.
- getName: Retrieves the name of the parameter.
- getType: Retrieves the type of the parameter.
- hasInitializer: Checks if the parameter has a default value.
- getInitializer: Retrieves the default value of the parameter, if any.
- getTypeParameters: Retrieves all type parameters of the function.
To use the extractFunctions function, follow these steps:
- Initialize the project with the source file.
- Call
extractFunctionswith the initialized source file.
const sourceFile = initializeProject("path/to/your/file.ts");
const functions = extractFunctions(sourceFile);
console.log(functions);This will log an array of objects, each representing a function found in the specified TypeScript file.
In SwiftGen, after extracting functions, these are combined with other extracted elements (variables, enums, type aliases) to generate the Swift code.
let combinedFunctions: any[] = [];
inputFiles.forEach((filePath: string) => {
try {
const sourceFile = initializeProject(filePath);
combinedFunctions = combinedFunctions.concat(extractFunctions(sourceFile));
} catch (error) {
console.error(`Error processing file ${filePath}:`, error);
}
});The extractEnums function retrieves all enum nodes in the source file and maps them to an object containing the enum name and its members.
Here is the complete implementation of the extractEnums function:
function extractEnums(sourceFile: any) {
return sourceFile.getEnums().map((enumDecl: any) => ({
name: enumDecl.getName(),
members: enumDecl.getMembers().map((member: any) => member.getName())
}));
}- getEnums: Retrieves all enum nodes in the source file.
- map: Maps each enum node to an object containing its details.
- getName: Retrieves the name of the enum.
-
getMembers: Retrieves all members of the enum.
- getName: Retrieves the name of each enum member.
The extractTypeAliases function retrieves all type alias nodes in the source file and maps them to an object containing the type alias name and its properties.
Here is the complete implementation of the extractTypeAliases function:
function extractTypeAliases(sourceFile: any) {
return sourceFile.getTypeAliases().map((alias: any) => ({
name: alias.getName(),
properties: alias.getTypeNode().getType().getProperties().map((prop: any) => ({
name: prop.getName(),
type: convertType(prop.getTypeAtLocation(prop.getDeclarations()[0]).getText())
}))
}));
}- getTypeAliases: Retrieves all type alias nodes in the source file.
- map: Maps each type alias node to an object containing its details.
- getName: Retrieves the name of the type alias.
- getTypeNode: Retrieves the type node of the alias.
- getType: Retrieves the type of the node.
-
getProperties: Retrieves all properties of the type.
- getName: Retrieves the name of each property.
- getTypeAtLocation: Retrieves the type of the property at the specified location.
- getText: Retrieves the text representation of the type.
To use the extractEnums and extractTypeAliases functions, follow these steps:
- Initialize the project with the source file.
- Call
extractEnumsandextractTypeAliaseswith the initialized source file.
const sourceFile = initializeProject("path/to/your/file.ts");
const enums = extractEnums(sourceFile);
const typeAliases = extractTypeAliases(sourceFile);
console.log(enums);
console.log(typeAliases);This will log arrays of objects, each representing an enum or type alias found in the specified TypeScript file.
In SwiftGen, after extracting enums and type aliases, these are combined with other extracted elements (variables, functions) to generate the Swift code.
let combinedEnums: any[] = [];
let combinedTypeAliases: any[] = [];
inputFiles.forEach((filePath: string) => {
try {
const sourceFile = initializeProject(filePath);
combinedEnums = combinedEnums.concat(extractEnums(sourceFile));
combinedTypeAliases = combinedTypeAliases.concat(extractTypeAliases(sourceFile));
} catch (error) {
console.error(`Error processing file ${filePath}:`, error);
}
});