Skip to content

SwiftGen

Justin Bush edited this page May 21, 2024 · 4 revisions

See the package details here: https://github.com/TypeSwift/SwiftGen

Overview

SwiftGen is a tool designed to convert TypeScript code into Swift code. This documentation provides a detailed overview of the extraction process used by SwiftGen to convert TypeScript variables, functions, enums and type aliases into their Swift equivalents.

Configuration

The tool reads its configuration from a config.json file. Make sure this file is correctly set up before running SwiftGen. Below is an example of what the configuration file should look like:

{
  "inputDir": "path/to/your/typescript/files",
  "outputDir": "path/to/output/swift/files",
  "outputFileName": "TypeSwift",
  "outputSuffix": ".swift"
}

Initialization

SwiftGen starts by initializing the project and reading the necessary configuration files. It first imports the required modules and reads the configuration and package information.

import { Project } from "ts-morph";
import path from 'path';
import fs from 'fs';
import { readConfig, writeSwiftCodeToFile, getAllFiles } from './utils/fileUtils';
import { convertType } from "./utils/typeMap";
import { generateSwiftCode } from './gen/swiftCodeGen';

console.log("Starting SwiftGen...");

// Read configuration file
const configPath = path.join(__dirname, 'config/config.json');
const config = readConfig(configPath);

console.log("Configuration loaded:", config);

// Read package.json file
const packageJsonPath = path.join(__dirname, '..', 'package.json');
const packageInfo = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));

Project Initialization

The initializeProject function initializes the TypeScript project and adds the source files. It takes a file path as an argument and returns the source file added to the project.

function initializeProject(filePath: string) {
  const project = new Project();
  return project.addSourceFileAtPath(filePath);
}

Variable Extraction

The extractVariables function extracts all variable statements from a given source file. It retrieves all variable declarations and maps them to their names.

function extractVariables(sourceFile: any) {
  return sourceFile.getVariableStatements()
    .flatMap((statement: any) => statement.getDeclarations().map((decl: any) => decl.getName()));
}

Function Extraction

The extractFunctions function extracts all functions, including their parameters and type parameters. It maps each function to its name, parameters (including their names, types, and default values), and type parameters.

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())
  }));
}

Enum Extraction

The extractEnums function extracts all enums and their members from the source file. It maps each enum to its name and members.

function extractEnums(sourceFile: any) {
  return sourceFile.getEnums().map((enumDecl: any) => ({
    name: enumDecl.getName(),
    members: enumDecl.getMembers().map((member: any) => member.getName())
  }));
}

Type Alias Extraction

The extractTypeAliases function extracts all type aliases and their properties. It maps each type alias to its name and properties, converting the property types as needed.

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())
    }))
  }));
}

Main Execution

SwiftGen processes all input files and generates the corresponding Swift code. It combines the extracted variables, functions, enums, and type aliases, and then generates the Swift code using the generateSwiftCode function. Finally, it writes the Swift code to the specified output directory and file.

const inputDir = config.inputDir;
console.log("Input directory:", inputDir);
const inputFiles = getAllFiles(inputDir);
console.log("Input files:", inputFiles);

let combinedVariables: string[] = [];
let combinedFunctions: any[] = [];
let combinedEnums: any[] = [];
let combinedTypeAliases: any[] = [];

inputFiles.forEach((filePath: string) => {
  try {
    const sourceFile = initializeProject(filePath);
    combinedVariables = combinedVariables.concat(extractVariables(sourceFile));
    combinedFunctions = combinedFunctions.concat(extractFunctions(sourceFile));
    combinedEnums = combinedEnums.concat(extractEnums(sourceFile));
    combinedTypeAliases = combinedTypeAliases.concat(extractTypeAliases(sourceFile));
  } catch (error) {
    console.error(`Error processing file ${filePath}:`, error);
  }
});

const swiftCode = generateSwiftCode(combinedVariables, combinedFunctions, combinedEnums, combinedTypeAliases, packageInfo);
writeSwiftCodeToFile(swiftCode, config.outputDir, config.outputFileName, config.outputSuffix);

console.log("SwiftGen completed.");

Clone this wiki locally